/* sigsuspend()函數說明 */ #include <stdio.h> #include <signal.h> /* 知識補充: sigsuspend()函數 函數原型: #include <signal.h> int sigsuspend(const sigset_t *mask); 參數說明: @mask 希望屏蔽的信號 返回值: sigsuspend返回后將恢復調用之前的的信號掩碼。信號處理函數完成后,進程將繼續執行。該系統調用始終返回-1,並將errno設置為EINTR. 備注: 進程執行到sigsuspend時,sigsuspend並不會立刻返回,進程處於TASK_INTERRUPTIBLE狀態並立刻放棄CPU, 等待UNBLOCK(mask之外的)信號的喚醒。進程在接收到UNBLOCK(mask之外)信號后,調用處理函數,然后還原信號集, sigsuspend返回,進程恢復執行。 使用場景: sigsuspend() 函數可以更改進程的信號屏蔽字可以阻塞所選擇的信號,或解除對它們的阻塞。 使用這種技術可以保護不希望由信號中斷的代碼臨界區。 如果希望對一個信號解除阻塞,然后pause等待以前被阻塞的信號發生,那么必須使用 sigsuspend() 函數 pause() 函數無法達成上述目的 //a.阻塞信號 if(sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) err_sys("SIG_BLOCK error"); //b.解除阻塞 if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) err_sys("SIG_SETMASK error"); //c.等待信號 pause(); 說明: 如果在等待信號階段,發送信號給程序,那么 pause()函數退出,處理信號 如果在解除阻塞之前發送信號,信號一被解除,立馬執行信號處理函數,執行完畢后,回來執行 pause()函數,程序被卡住 為了糾正此問題,需要在一個原子操作中先恢復信號屏蔽字,然后使進程休眠。這種功能是由 sigsuspend() 函數提供的。 */ void test() { sigset_t set; //1.設置需要處理的信號 sigemptyset(&set); sigaddset(&set, SIGCHLD); sigaddset(&set, SIGALRM); sigaddset(&set, SIGIO); sigaddset(&set, SIGINT); //2.先屏蔽這些信號 if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) { printf("sigprocmask() failed .\n"); return; } //3.做一些初始化操作 //4.開始接收這些信號 sigemptyset(&set); //清空信號集 sigsuspend(&set); //等待信號過來處理 } int main() { test(); printf("-----ok-------\n"); return 0; }