sigsuspend函數 :
sigsuspend函數接受一個信號集指針,將信號屏蔽字設置爲信號集中的值,在進程接受到一個信號之前,進程會掛起,當捕捉一個信
號,首先執行信號處理程序,然後從sigsuspend返回,最後將信號屏蔽字恢復爲調用sigsuspend之前的值。
#include <signal.h>
int sigsuspend(const sigset_t *sigmask);
// 返回值:-1,並將errno設置爲EINTR
pause函數:
pause函數使調用進程掛起直到捕捉到一個信號。只有執行了一個信號處理程序並從其返回時,pause才返回
先看個例子:
1 #include <stdio.h>
2 #include <signal.h>
3 #include <unistd.h>
4 #include <string.h>
5
6 void func(int num)
7 {
8 printf("0\n");
9 }
10
11 int main(void)
12 {
13 int i;
14 sigset_t set;
15 sigset_t empty;
16
17 sigemptyset(&set);
18 sigemptyset(&empty);
19 sigaddset(&set, SIGINT);
20 signal(SIGINT, func);
21
22 while(1)
23 {
24 sigprocmask(SIG_BLOCK, &set, NULL);
25 for(i = 0; i < 5 ; i++)
26 {
27 write(1, "* ", strlen("* "));
28 sleep(1);
29 }
30 printf("\n");
31 #if 1
32 sigsuspend(&empty);
33 #else
34 sigprocmask(SIG_UNBLOCK, &set, NULL);
35 pause();
36 #endif
37 }
38
39 return 0;
40 }
[root@localhost lee]# ./a.out // 31 #if 1 時
* * * * *
0
* * * * *
0
* * 退出
[root@localhost lee]# ./a.out // 31 #if 0 時
* * * * *
0
0
* * * * *
區別:sigsuspend 未打印到5 個星時,中間 ctrl+c 中斷,5個到之後會自動換行繼續執行。
pause 則繼續func函數後,不會繼續往下執行。需再中斷一次。
程序夠明白了,不用再多說。
sigsuspend的整個原子操作過程爲:
(1) 設置新的mask阻塞當前進程;
(2) 收到信號,調用該進程設置的信號處理函數;
(3) 待信號處理函數返回後,恢復原先mask;
(4) sigsuspend返回
----------------------------------補充:
1. sigpromask(SIG_UNBLOCK,&newmask,&oldmask)和
sigpromask(SIG_SETMASK,&oldmask,NULL)區別
sigpromask(SIG_UNBLOCK,&newmask,&oldmask)
它的作用有兩個:一是設置新的信號掩碼(不阻塞newmask所指的信號集).二是保存原來的信號掩碼(放在oldmask所指的信號集中)
sigpromask(SIG_SETMASK,&oldmask,NULL)
它的作用只有一個:設置新的信號掩碼(信號掩碼爲oldmask所指的信號集)
2. sigsuspend 用實參 sigmask 指定的信號集代替調用進程的信號屏蔽, 然後掛起該進程直到某個不屬於 sigmask 成員的信號到
達爲止。此信號的動作要麼是執行信號句柄,要麼是終止該進程。
如果信號終止進程,則 suspend 函數不返回。如果信號的動作是執行信號句柄,則在信號句柄返回後,sigsuspend 函數返回,並使
進程的信號屏蔽恢復到 sigsuspend 調用之前的值。
3. 清晰且可靠的等待信號到達的方法是先阻塞該信號(防止臨界區重入,也就是在次期間有另外一個該信號到達),然後使用
sigsuspend 放開此信號並等待句柄設置信號到達標誌。如下所示, 等待 SIGUSR1 信號到來:
sigemptyset(&zeromask);
sigaddset(&newmask, SIGUSR1);
......
sigprocmask(SIG_BLOCK, &newmask, NULL);
while(flag)
sigsuspend(&zeromask);
flag = 0;
......
sigprocmask(SIG_UNBLOCK, &newmask, NULL);
轉自:http://blog.csdn.net/liwentao1091/article/details/6619089