簡體   English   中英

如果信號處理程序在處理時接收到另一個信號,它將如何工作?

[英]How exactly signal handler will work if it receives another signal while processed?

我試圖測試信號處理程序中到底發生了什么。

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....

我對信號處理程序的想法有什么誤解嗎? 我很困惑。

這是你的誤解:

並且第一個處理程序將在這里退出,並且 num ++ 將不起作用。

當一個信號處理程序中斷另一個信號處理程序時,一旦中斷處理程序完成,被中斷的處理程序將從中斷處恢復。 它不只是提前結束。

順便說一句,你的代碼有很多問題:

  1. 由於您沒有使用SA_SIGINFO ,因此您的handler應該只接受一個參數,並且應該進入sa_handler而不是sa_sigaction
  2. 您沒有初始化struct sigaction的大多數字段,因此當您在其上調用sigaction時,最終可能會發生非常奇怪的事情。
  3. 您在信號處理程序內部可以執行的操作確實受到限制; 特別是,您不允許訪問int類型的全局變量。 num更改為volatile sig_atomic_t
  4. 您基本上不應該在循環之外使用write ,因為基本上任何時候都允許部分寫入發生。

至於為什么發送SIGUSR1兩次並不總是運行處理程序兩次,那是因為允許非實時信號合並,所以如果你的第二次kill發生在第一個信號處理程序開始運行之前,那么第二個有效不會做任何事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM