sigsuspend的主要作用就是阻塞进程直至捕获到信号,在讲该函数前先回顾一下上一篇介绍的下信号延迟处理的方法,先贴一下上一篇文章中的实现代码:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <signal.h> 5 #include <unistd.h> 6 void sigfunc(int signum); 7 int main() 8 { 9 sigset_t newsigset, oldsigset, pendsigset; 10 //1-设置捕获信号 11 signal(SIGINT, sigfunc); 12 //2-初始化信号集 13 sigemptyset(&newsigset); 14 //3-添加待处理信号集 15 sigaddset(&newsigset, SIGINT); 16 //4-设置阻塞信号集 17 sigprocmask(SIG_BLOCK, &newsigset, &oldsigset); 18 //5-休眠 19 for (int i=0; i<5; ++i) 20 { 21 printf("sleeping %d\n", i); 22 sleep(1); 23 } 24 //6-检查获取到的被阻塞的信号集 25 sigpending(&pendsigset); 26 printf("SIGINT is blocked %d\n", sigismember(&pendsigset, SIGINT)); 27 //7-还原被屏蔽的信号集 28 printf("recover signal \n"); 29 sigprocmask(SIG_SETMASK, &oldsigset, 0); 30 return 0; 31 } 32 33 void sigfunc(int signum) 34 { 35 printf("catch SIGINT | signum = %d\n", signum); 36 }
上述代码中,在sigprocmask(SIG_BLOCK, &newsigset, &oldsigset);后休眠了5秒,如果在5秒内收到SIGINT的话则该信号会延迟到5秒之后的sigprocmask(SIG_SETMASK, &oldsigset, 0);之后处理,但如果5秒内没有收到SIGINT信号,程序顺序执行,直接退出。即使在sigprocmask(SIG_SETMASK, &oldsigset, 0);之后添加pause,那么也可能在两个之间收到SIGINT信号,从而导致程序一直处于pause状态。
而sigsuspend则可以解决上述问题。sigsuspend会阻塞进程直至捕获到信号,使程序不会在捕获信号前直接退出,又由于是原子操作,所以不会出现在sigprocmask(SIG_SETMASK, &oldsigset, 0);和pause中间出现SIGINT导致进程一直pause。
示例代码如下:
1 #include <signal.h> 2 #include <stdio.h> 3 #include <string.h> 4 #include <stdlib.h> 5 #include <unistd.h> 6 7 void handler(int signum) 8 { 9 printf("signum=%d\n", signum); 10 } 11 12 int main() 13 { 14 signal(SIGINT, handler); 15 sigset_t newsigset, oldsigset, suspendsigset; 16 sigemptyset(&newsigset); 17 sigemptyset(&suspendsigset); 18 sigaddset(&newsigset, SIGINT); 19 sigaddset(&suspendsigset, SIGUSR1); 20 21 sigprocmask(SIG_BLOCK, &newsigset, &oldsigset); 22 23 for (int i=0; i<5; ++i) 24 { 25 printf("sleeping i=%d\n", i); 26 sleep(1); 27 } 28 29 sigsuspend(&suspendsigset); 30 31 sigprocmask(SIG_SETMASK, &oldsigset, NULL); 32 33 return 0; 34 }
时间: 2024-10-06 13:14:53