这篇文章上次修改于 718 天前,可能其部分内容已经发生变化,如有疑问可询问作者。
信号可以屏蔽,也可以捕捉
信号屏蔽(阻塞)
sigset_t set;//初始化信号集
sigemptyset(&set);//清空信号集
sigaddset(&set, SIGINT);//信号加入信号集
sigprocmask(SIG_BLOCK,&set, NULL);//设置屏蔽信号(堵塞,解除后恢复)
sigprocmask(SIG_UNBLOCK,&set, NULL);//解除屏蔽
详解sigprocmask
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
set自定义位图
old保存旧位图
how有
1. SIG_BLOCK: set 表示需要屏蔽的信号。相当于 mask = mask|set
2. SIG_UNBLOCK: set 表示需要解除屏蔽的信号。相当于 mask = mask & ~set
3. SIG_SETMASK: set 表示用于替代原始屏蔽及的新屏蔽集。相当于 mask = set 若,调用 sigprocmask 解除了对当前若干个信号的阻塞,则在 sigprocmask 返回前,至少将其中一 个信号递达。
信号捕捉(自定义)
1.捕捉函数(void)fun(int)
void er(int number)//信号捕捉函数 (void)func(int)
{
if (number == SIGINT)
printf("hello\n");
else if(number==SIGCHLD)
{
pid_t wpid;
int status;
while((wpid=waitpid(-1,&status,0))!=-1)//防止多个进程同时死亡
{
if(WIFEXITED(status))
printf("%d",WEXISTATUS(ststus));
}
}
return;
}
2.先阻塞
sigset_t set;//初始化信号集
sigemptyset(&set);//清空信号集
sigaddset(&set, SIGCHLD);//SIGCHLD信号加入信号集
sigprocmask(SIG_BLOCK,&set, NULL);//设置屏蔽信号(堵塞,解除后恢复,只处理一次)
3.再注册
struct sigaction new, old;
new.sa_handler = er; //执行函数名(先写捕捉函数)
sigemptyset(&new.sa_mask); //清空捕捉屏蔽字
new.sa_flags = 0; //0 默认操作(屏蔽本信号)设置捕捉屏蔽字
sigaction(SIGCHLD,&new,&old); //信号SIGCHLD 子进程状态变化
4.再解除阻塞
sigprocmask(SIG_UNBLOCK,&set, NULL);//解除屏蔽(处理一次)
关于sigaction与struct sigaction
注意3点
new.sa_handler = er; //执行函数名
sigemptyset(&new.sa_mask); //清空捕捉屏蔽字
new.sa_flags = 0; //0 默认操作(屏蔽本信号)设置捕捉屏蔽字
函数原型(详解struct sigaction)
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
struct sigaction
{
1:
void (*sa_handler)(int);
//指定信号捕捉后的处理函数名(即注册函数)。也可赋值为 SIG_IGN表忽略 或 SIG_DFL 表执行默认动作
2:
sigset_t sa_mask;
//sa_mask: 调用信号处理函数时,所要屏蔽的信号集合(信号屏蔽字)。注意:仅在处理函数被调用期间屏蔽生效,是临时性设置
3:
int sa_flags;
//sa_flags:通常设置为 0,表使用默认属性
//重启函数 SA_INTERRURT 不重启。 SA_RESTART 重启
other:
// void (*sa_sigaction )(int, siginfo_t *, void *);(进程间通信)
// void (*sa_restorer)(void);
}
没有评论