可靠信号、不可靠信号的观察案例:
1、创建子进程和父进程
2、注册SIGINT非实时信号 SIGRTMIN实时信号 添加到进程阻塞中
3、注册用户自定义信号SIGUSR1
4、子进程发送3次非实时信号,发3次实时信号
5、子进程发送SIGUSR1解除信号阻塞
6、观察实时信号和非实时信号的表现与区别
//基础版实现
#include<sys/wait.h>
#include<sys/types.h>
#include<fcnt1.h>
#include<stdlib.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>
#include<signal.h>
#define ERR_EXIT(m)
do
{
perror(m);
exit(EXIT_FAILURE);
}while(0)
void myhandle(int num)
{
if(num == SIGUSR1)
{
// 把 SIGINT 和 SIGRTMIN均添加到本进程的解除阻塞状态字中
sigset_t bset;
sigemptyset(&bset);
sigaddset(&bset, SIGINT);
sigaddset(&bset, SIGRTMIN);
sigprocmask(SIG_UNBLOCK, &bset, NULL);
print("解除阻塞: %d \n", num);
}
else if(num == SIGINT || num ==SIGRTMIN)
{
print("recv sig num: %d \n", num);
}
else
{
print("其他信号 \n");
}
}
void main()
{
pid_t pid;
struct sigaction act;
act.sa_handler = myhanlde;
act.sa_flages = SA_SIGINFO;
//注册非实时信号 处理函数 使用 “kill -l“ 查询信号名称
if( sigaction(SIGINT, &act, NULL) < 0 ) //注册信号,如果小于零,则说明注册错误
{
ERR_EXIT("sigaction SIGINT");
}
//注册实时信号 处理函数
if( sigaction(SIGRTMIN, &act, NULL) < 0 ) //注册信号,如果小于零,则说明注册错误
{
ERR_EXIT("sigaction SIGRTMIN");
}
//注册用户自定义信号 SIGUSR1
if( sigaction(SIGUSR1, &act, NULL) < 0 ) //注册信号,如果小于零,则说明注册错误
{
ERR_EXIT("sigaction SIGUSR1");
}
// 使用man 2 sigprocmask 查手册
// int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
// man sigaddset 查询手册,看使用方法
// 把 SIGINT 和 SIGRTMIN均添加到本进程的阻塞状态字中
sigset_t bset;
sigemptyset(&bset);
sigaddset(&bset, SIGINT);
sigaddset(&bset, SIGRTMIN);
sigprocmask(SIG_BLOCK, &bset, NULL);
pid = fork();
if(pid == -1)
{
ERR_EXIT("fork err");
}
if(pid == 0) //子进程
{
int i = 0;
int ret = 0;
union sigval v;
v.sival_int = 308;
//发三次不稳定信号
for(i=0; i<3; i++)
{
ret = sigqueue(getppid(), SIGINT, v);
if(ret != 0)
{
printf("发送不可靠信号失败ret: %d, errno:%d \n", ret, errno);
exit(0); //报错的话直接退出
}
printf("发送不可靠信号成功\n");
}
v.sival_int = 508;
//发三次稳定信号
for(i=0; i<3; i++)
{
ret = sigqueue(getppid(), SIGRTMIN, v);
if(ret != 0)
{
printf("发送可靠信号失败ret: %d, errno:%d \n", ret, errno);
exit(0); //报错的话直接退出
}
printf("发送可靠信号成功\n");
}
//向父进程发送解除阻塞信号
kill(getppid(), SIGUSR1);
}
while(1)
{
sleep(1);
}
print("main....\n");
}