#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
/*
1. 创建子进程和父进程
2. 注册 SIGINT 非实时信号 SIGRTMIN 实时信号,添加到进程阻塞中
3. 注册用户自定义信号 SIGQUIT
4. 子进程发送3次非实时信号,发3次实时信号
5. 子进程发送SIGQUIT解除信号阻塞
6. 观察实时信号和非实时信号的表现与区别
*/
// int sigprocmask(int how, const sigset_t *set, sigset_t *oldset); -----> 设置信号阻塞或非阻塞
// int sigaction(int signum, const struct sigaction *act, -----> 信号安装函数
// struct sigaction *oldact);
void handle(int signum, siginfo_t *info, void *p);
int main(void)
{
pid_t fpid, pid;
sigset_t mset; // 信号集
struct sigaction act; // act结构体中含信号处理函数
act.sa_sigaction = handle; // 信号处理函数
act.sa_flags = SA_SIGINFO; // 标志位为SA_SIGINFO时,sigaction函数才能接收sigqueue发送的信号
// 安装三个信号,一个实时(SIGRTMIN),一个非实时(SIGINT),一个通过键盘发送信号测试程序(SIGQUIT)
sigaction(SIGINT, &act, NULL);
sigaction(SIGRTMIN, &act, NULL);
sigaction(SIGQUIT, &act, NULL);
// 设置实时和非实时信号阻塞
sigemptyset(&mset);
sigaddset(&mset, SIGINT);
sigaddset(&mset, SIGRTMIN);
sigprocmask(SIG_BLOCK, &mset, NULL);
fpid = fork();
if (fpid == -1) {
perror("MSG");
exit(0);
}
// int sigqueue(pid_t pid, int sig, const union sigval value);
if (fpid == 0) {
union sigval value;
int i = 0, ret = 0;
pid = getppid();
for (i = 1; i < 4; i++) {
value.sival_int = i;
// 给父进程发送信号, 3个非实时信号
ret = sigqueue(pid, SIGINT, value);
if (ret != 0) {
printf("发送非实时信号失败\n");
}
printf("发送非实时信号成功\n");
}
for (i = 1; i < 4; i++) {
value.sival_int = i;
// 给父进程发送信号,3个非实时信号
ret = sigqueue(pid, SIGRTMIN, value);
if (ret != 0) {
printf("发送实时信号失败\n");
}
printf("发送实时信号成功\n");
}
value.sival_int = 1942;
//sigqueue(pid, SIGQUIT, value);
}
while (1) {
pause();
}
return 0;
}
// 信号处理函数,当被阻塞时,不会调用此函数
void handle(int signum, siginfo_t *info, void *p)
{
int num = 0;
num = info->si_value.sival_int;
if (signum == SIGINT) {
printf("recv signal %d\n", signum);
printf("recv value %d\n", num);
}
if (signum == SIGRTMIN) {
printf("recv signal %d\n", signum);
printf("recv value %d\n", num);
}
// 通过键盘发送SIGQUIT信号时,会执行下面的代码,作用:
// 解除阻塞信号集,解除后,进程会执行上面两个if分支,非实时信号会丢失,三个丢失了两个
// 实时信号没有丢失
if (signum == SIGQUIT) {
sigset_t uset;
sigemptyset(&uset);
sigaddset(&uset, SIGINT);
sigaddset(&uset, SIGRTMIN);
sigprocmask(SIG_UNBLOCK, &uset, NULL);
printf("SIGINT and SIGRTMIN 已经解除阻塞\n");
}
}
/*
运行结果:
[root@Mysql-dev signal]# ./sigaction
发送非实时信号成功
发送非实时信号成功
发送非实时信号成功
发送实时信号成功
发送实时信号成功
发送实时信号成功
^\SIGINT and SIGRTMIN 已经解除阻塞
recv signal 2
recv value 1
recv signal 34
recv value 1
recv signal 34
recv value 2
recv signal 34
recv value 3
SIGINT and SIGRTMIN 已经解除阻塞
可以看到发送的时候,都是三个,解除阻塞接受的时候,只有实时信号没有被丢失,非实时信号丢失了两个
*/
可靠信号和不可靠信号的测试
最新推荐文章于 2021-12-29 16:21:22 发布