sigsuspend 函數使用 及與 pause 區別

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>

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章