群里问 , 用信号处理函数还需要考虑可重入问题 , 各种中断调用, 有没有简单的方法;
sigwaitinfo(sigset_t * set , siginfo_t * info) ;
阻塞函数, 用来同步化的解决信号问题; 一旦待检测的 sigset_t * set 中有任一信号发生(pending) 即返回此信号,
由于他检测的是pending信号, 话外之意就是你应该使用sigprocmask 来屏蔽待检测 set 中的信号
比如你要等待一个SIGINT信号:
sigset_t mask;
siginfo_t info;
sigaddset(&mask,SIGINT);
sigprocmask(SIG_BLOCK, &mask,NULL);
int signo = sigwaitinfo(&mask,&info);
下面是完整的例子:
#include <signal.h>
#include <sys/mman.h>
#include <semaphore.h>
#include <sys/types.h>
#include <sys/wait.h>
//SIGQUIT 用
void handler(int s){
printf("handler :%d\n" ,s);
}
int main(int argc, char**argv)
{
signal(SIGQUIT ,handler); // ctrl + \, 此信号没BLOCK
siginfo_t info;
sigset_t mask;
//sigfillset(&mask);
sigaddset(&mask,SIGRTMIN+1);
sigaddset(&mask , SIGRTMIN+2);
sigprocmask(SIG_BLOCK, &mask,NULL); //设置屏蔽
int pid = fork();
if(0 == pid){
//child
puts("child start");
kill(getppid(), SIGRTMIN+1); //或用sigqueue
kill(getppid(),SIGRTMIN+2);
kill(getppid(), SIGRTMIN+1);
return 0;
}
//parent
int sig = -1;
while(1){
//阻塞等待
sig = sigwaitinfo(&mask,&info);
if(sig < 0){
if(errno == EINTR) {
// 上面 sigquit 将在这里中断
perror("sigwaitinfo ");
continue;
}
printf("parent error:%s\n" , strerror(errno));
break;
}
//回收子进程
if(SIGCHLD == sig){
puts("child is done");
while(waitpid(-1,0,WNOHANG) > 0);
}
printf("sig:%d , from pid:%d , code:%d , signo:%d\n" , sig, info.si_pid,info.si_code,info.si_signo);
//ctrl+c 就结束了
if(SIGINT == sig){
break;
}
}
return 0;
}
还有个附带超时功能的 sigtimedwait , 就比sigwaitinfo多一个时间参数, 我就不写了
还有一个相同能的sigwait , 用法类似, 不写了, 特别想睡觉;