Linux信号处理函数可中断么,linux中关于信号处理笔记(一)
#include static void sig_quit(int);
int main(void)
{
sigset_t newmask, oldmask, pendmask;
if(signal(SIGQUIT, sig_quit) == SIG_ERR)
{
printf("can not catch SIGQUIT");
exit(1);
}
sigemptyset(&newmask);//使用前先設置sigset_t結構
sigaddset(&newmask, SIGQUIT);
if(sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)//設置阻塞信號
{
printf("sig_block error");
exit(1);
}
sleep(5);//在5秒內按下鍵盤上“ctrl” + “\”,會產生SIGQUIT信號,這時候這個信號就是已經發出,但是被阻塞,未決的信號
if(sigpending(&pendmask) < 0)
{
printf("sigpending error");
exit(1);
}
if(sigismember(&pendmask, SIGQUIT))
{
printf("\nSIGQUIT pending\n");//這里會打印信息,說明信號未決
}
if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)//回復默認信號動作,執行這個程序的時候,會發現先打印信號處理函數中的內容,再打印下面的內容,從而證明了上面對sigprocmask函數的說明。
{
printf("SIG_SETMASK error");
exit(1);
}
printf("sigquit unblocked\n");
sleep(5);
exit(0);
}
static void sig_quit(int signo)
{
printf("caught SIGQUIT\n");
if(signal(SIGQUIT, SIG_DFL) == SIG_ERR)
{
printf("can not reset sigquit\n");
exit(1);
}
}
六 sigsuspend函數
更改信號屏蔽字可以阻塞所選信號,或解除對它們的阻塞。使用這種技術可以保護部希望由信號中斷的代碼區域。
如果希望對一個信號解決阻塞,然后pause以等待以前被阻塞的信號,如何實現呢?
sigset_t newmask, oldmask;
sigemptyset(&newmask);
sigaddset(&newmask, SIGINT);
if(sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
exit(1);
/* critical region of code*/
if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
exit(1);
pause();
..........
首先說明,這是個不理想的做法。如果信號發生在阻塞時,等解除阻塞時執行信號處理函數以后,pause返回,然后執行后面的程序。
pause函數:pause函數使調用進程掛起直至捕捉到一個信號,只有執行了一個信號處理函數并從其返回時,pause才返回。
如果在解除阻塞時刻和pause之間發生了信號,就丟失了。這樣pause就一直掛在那等信號,這就是早期不可靠信號的機制的一個問題。
為了修正上面問題,需要在一個原子操作中先恢復信號屏蔽字,然后使進程休眠,這個功能就是由sigsuspend函數提供的。
int ?sigsuspend(const sigset_t *sigmask);
這個函數在一個不可中斷的過程當中執行下面過程:
將進程的信號屏蔽字設置為sigmask指向的值,然后掛起,等待特定的信號,然后捕捉到一個信號并且從信號處理程序返回,則sigsuspend返回,
并且將給進程的信號屏蔽字設置為調用sigsuspend之前的值。
這個函數沒有成功返回值,它總是返回-1,并置errno為EINTR。下面是幾個sigsuspend應用實例:
幾個實例等下期再寫吧,今天下班。
1 ?保護臨界區不被信號中斷
總結
以上是生活随笔為你收集整理的Linux信号处理函数可中断么,linux中关于信号处理笔记(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux修改网卡文件夹,CentOS7
- 下一篇: linux卸载模块驱动程序,Linux设