博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux下关于信号block与unblock的小研究
阅读量:4940 次
发布时间:2019-06-11

本文共 4741 字,大约阅读时间需要 15 分钟。

Linux下当向一个进程发出信号时,从信号产生到进程接收该信号并执行相应操作的过程称为信号的等待过程(呃,根据对APUE的理解翻译的)。如果某一个信号没有被进程屏蔽,则我们可以在程序中阻塞进程对该信号所相应的操作。例如一个程序当接收到SIGUSR1信号时会进行一个操作,我们可以利用系统API阻塞(block)程序对该信号的操作,直到我们解除阻止。再举个现实的例子:就好像一个同学让我帮他带饭,但是我现在有其他事要做,现在我先做我手头上的事,直到我把手上的事都完成才去帮他带饭。整个过程差不多就是这样子。

我们考虑多线程与非多线程的情况。

下来我们来看一段代码,这个程序接收到usr1,usr2信号会设置两个全局变量usr1和usr2的值为1。主程序中有两个循环,第一个循环接收到usr1信号会跳出循环,第二个循环接收到usr1,usr2信号都会跳出循环。

1 #include
2 #include
3 #include
4 5 int flag_sigusr1 = 0; 6 int flag_sigusr2 = 0; 7 8 void sig_usr1(int signo){
9 fprintf(stdout, "caught SIGUSR1\n"); 10 flag_sigusr1 = 1; 11 return; 12 } 13 14 void sig_usr2(int signo){
15 fprintf(stdout, "caught SIGUSR2\n"); 16 flag_sigusr2 = 1; 17 return; 18 } 19 20 int main(void){
21 sigset_t newmask, oldmask; 22 23 signal(SIGUSR1, sig_usr1); 24 signal(SIGUSR2, sig_usr2); 25 26 fprintf(stdout, "first while. catch sigusr1 can break\n"); 27 while(1){
28 if(flag_sigusr1){
29 fprintf(stdout, "break"); 30 break; 31 } 32 sleep(10); 33 } 34 flag_sigusr1 = 0; 35 36 //block SIGUSR1 37 sigemptyset(&newmask); 38 sigaddset(&newmask, SIGUSR1); 39 if(sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0){
40 perror("sigprocmask error"); 41 } 42 43 fprintf(stdout, "first while. catch sigusr1 or sigusr2 can break\n"); 44 while(1){
45 if(flag_sigusr1 || flag_sigusr2){
46 fprintf(stdout, "break"); 47 break; 48 } 49 sleep(10); 50 } 51 52 return 0; 53 }

第一个循环和第二个循环之间我们选择阻塞sigusr1信号,所以当程序运行到第二个循环时向程序发送usr1信号时并不会跳出循环。

多线程情况下每个线程共用信号处理函数,但是每个线程可以选择自己是否block某个信号。

再看一个多线程的例子:子线程的功能同上,主线程接收到hup信号会向子线程发送usr2信号。

1 #include
2 #include
3 #include
4 #include
5 6 int flag_sigusr1 = 0; 7 int flag_sigusr2 = 0; 8 int flag_sighup = 0; 9 10 void sig_usr1(int signo){
11 fprintf(stdout, "sig|caught SIGUSR1\n"); 12 flag_sigusr1 = 1; 13 return; 14 } 15 16 void sig_usr2(int signo){
17 fprintf(stdout, "sig|caught SIGUSR2\n"); 18 flag_sigusr2 = 1; 19 return; 20 } 21 22 void sig_hup(int signo){
23 fprintf(stdout, "sig|caught SIGHUP\n"); 24 flag_sighup = 1; 25 return; 26 } 27 28 void *thread_control_signal(void *arg){
29 sigset_t newmask, oldmask; 30 sigemptyset(&newmask); 31 32 //thread block sighup 33 sigemptyset(&newmask); 34 sigaddset(&newmask, SIGHUP); 35 if(pthread_sigmask(SIG_BLOCK, &newmask, &oldmask) < 0){ 36 perror("sigprocmask error"); 37 } 38 39 fprintf(stdout, "thread|first while. catch sigusr1 or sigusr2 can break\n"); 40 while(1){
41 if(flag_sigusr1 || flag_sigusr2){
42 fprintf(stdout, "thread|break\n"); 43 44 break; 45 } 46 sleep(10); 47 } 48 flag_sigusr1 = 0; 49 50 //thread block SIGUSR1 51 sigaddset(&newmask, SIGUSR1); 52 if(pthread_sigmask(SIG_BLOCK, &newmask, &oldmask) < 0){
53 perror("sigprocmask error"); 54 } 55 56 fprintf(stdout, "thread|first while. catch sigusr2 can break\n"); 57 while(1){
58 if(flag_sigusr1 || flag_sigusr2){
59 fprintf(stdout, "break\n"); 60 break; 61 } 62 sleep(10); 63 } 64 65 fprintf(stdout, "thread|thread exit\n"); 66 return (void *)0; 67 } 68 69 int main(void){
70 sigset_t newmask; 71 pthread_t tid; 72 int signo; 73 74 //signal action 75 signal(SIGUSR1, sig_usr1); 76 signal(SIGUSR2, sig_usr2); 77 signal(SIGHUP , sig_hup); 78 79 if(pthread_create(&tid, NULL, thread_control_signal, NULL) < 0){
80 perror("create pthread failed"); 81 return -1; 82 } 83 84 //main thread block sigusr1 85 sigemptyset(&newmask); 86 sigaddset(&newmask, SIGUSR1); 87 if(pthread_sigmask(SIG_BLOCK, &newmask, NULL) < 0){
88 perror("sigprocmask error"); 89 } 90 91 //main thread wait sighup 92 sigemptyset(&newmask); 93 sigaddset(&newmask, SIGHUP); 94 if(sigwait(&newmask, &signo) < 0){
95 perror("sigwait failed"); 96 return -1; 97 } 98 fprintf(stdout, "main|get SIGHUP\n"); 99 100 pthread_kill(tid, SIGUSR2); 101 pthread_kill(tid, SIGUSR2); 102 pthread_join(tid, NULL); 103 104 fprintf(stdout, "main|exit\n"); 105 return 0; 106 }

over~

转载于:https://www.cnblogs.com/aLittleBitCool/archive/2011/12/29/2306574.html

你可能感兴趣的文章
<metro>Google的验证
查看>>
SQL中NUMERIC和DECIMAL的区别
查看>>
安卓课程设计:微课表
查看>>
Oracle 表的分组操作
查看>>
在OS X上的Intllij Idea中配置GlassFish
查看>>
用查表法快速转换yv12到RGB【转】
查看>>
使用公钥登录SSL
查看>>
hdu 1290_献给杭电五十周年校庆的礼物
查看>>
Nginx 入门
查看>>
openCR-用ROS代码点亮LED的方法
查看>>
豆瓣电影api
查看>>
BufferedInputStream和FileInputStream的区别
查看>>
二阶段之六
查看>>
微博爬虫 python
查看>>
中石油 【递归】普通递归关系
查看>>
vue报错Error in render: "TypeError: Cannot read property '0' of undefined"
查看>>
silverlight 隐藏ChildWindow 右上角的关闭按钮
查看>>
likely() 和 unlikely()
查看>>
03一些View总结
查看>>
MapReduce--平均分,最高,低分以及及格率的计算
查看>>