我試圖測驗信號處理程式中到底發生了什么。
int num = 0;
void handler(int signum, siginfo_t *sip, void *ptr)
{
sleep(1);
num ;
write(1, "processs!\n", 10);
}
int main(void)
{
int pid = getpid();
struct sigaction act1;
printf("%d\n", pid);
//act1.sa_flags = SA_NODEFER;
act1.sa_sigaction = &handler;
sigaction(SIGUSR1, &act1, NULL);
sigaction(SIGUSR2, &act1, NULL);
while (1)
{
sleep(1);
printf("%d\n", num);
};
}
在其他程序中,我因此發送兩個信號,如下所示: kill(pid, SIGUSR1); 殺死(PID,SIGUSR1);
據我所知,信號處理程式會阻止呼叫自己的信號.....并且在處理程式結束后處理阻塞的信號。我希望處理程式將被呼叫兩次,全域變數 num 將為 2;
但它只被呼叫了一次,并且 num 為 1。
然后我嘗試像這樣發送兩個不同的信號: kill(pid, SIGUSR1); 殺死(PID,SIGUSR2);
據我所知,SIGUSR2 將在處理程式仍處于睡眠狀態期間進行處理,并且第一個處理程式將在這里退出,并且 num 將不起作用。它只會在稍后呼叫的處理程式中處理一次。
但是在這次試驗中,處理程式被呼叫了兩次,num 為 2....
我對信號處理程式的想法有什么誤解嗎?我很困惑。
uj5u.com熱心網友回復:
這是你的誤解:
并且第一個處理程式將在這里退出,并且 num 將不起作用。
當一個信號處理程式中斷另一個信號處理程式時,一旦中斷處理程式完成,被中斷的處理程式將從中斷處恢復。它不只是提前結束。
順便說一句,你的代碼有很多問題:
- 由于您沒有使用
SA_SIGINFO
,因此您handler
應該只使用一個引數,并且應該輸入sa_handler
而不是sa_sigaction
. - 您沒有初始化 的大多數欄位
struct sigaction
,因此當您呼叫它時可能會發生非常奇怪的事情sigaction
。 - 您在信號處理程式內部可以執行的操作確實受到限制;特別是,您不允許訪問 type 的全域變數
int
。更改num
為volatile sig_atomic_t
. - 您基本上不應該
write
在回圈之外使用,因為基本上任何時候都允許部分寫入。
至于為什么發送SIGUSR1
兩次并不總是運行處理程式兩次,那是因為允許非實時信號合并,所以如果你的第二次kill
發生在第一個信號處理程式開始運行之前,那么第二個有效地不會'不做任何事。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/486267.html