2017-06-11 121 views
6

pause()功能塊直到信號到達。 假設進程得到了一個信號並且返回了pause(),那麼在調用pause()之後的代碼之前,信號處理程序是否會被執行,或者結果是意外的?暫停()信號處理程序

例子:

void sigusr1_handler() 
{ 
    // .. handler code 
} 

void main() 
{ 
    // .. bind handler to SIGUSR1 

    pause(); // wait for SIGUSR1 
    // some more code 
} 

是否「一些更多的代碼」將始終sigusr1_handler()完成後執行,或者是有競爭條件?如果是這樣,解決方案是什麼?
我想不出任何東西,除了忙等待,但隨後將不是在所有需要暫停..

+0

「or the result is unexpected」 - 我們如何知道您的期望? – Olaf

回答

7

the man page for pause(2)舉例:

暫停()只返回時的信號被捕獲並返回信號捕獲函數。在這種情況下,暫停()返回-1,並且errno設置爲EINTR

您可以確定您的信號處理程序在some more code之前運行。

3

信號處理程序不會同時運行;它們中斷處理它們的線程,並且中斷的流只在信號處理程序返回時繼續。

但是,可能存在與您的示例相關的其他競爭條件;只是稀疏的僞代碼,而不是對你的用例的完整解釋,這很難說。例如,一個不同的信號可能會在您的信號發出之前到達並中斷pause,然後您的處理程序可能會比預期的時間晚。

有幾個「正確的方式」來做到這一點,而不是:在信號處理程序

  • write一個字節到pipe,並在執行的主流read從它。
  • sem_post來自信號處理程序的信號量,以及sem_wait中的主要執行流程。
  • 使用sigwaitinfosigtimedwait代替信號處理程序。
  • 還在用pause,但在一個循環:

    while(!signal_handler_finished) pause(); 
    

    其中​​具有類型volatile sig_atomic_t,並且被設置爲在信號處理程序爲非零值。

+0

謝謝。我也使用sig_mask來阻止信號處理程序中的其他信號。這就是爲什麼我簡化了我的例子。只是想確保信號處理程序不會以'線程風格'運行,因此會受到競爭條件的影響。所以在我的情況下,暫停應該可以正常工作。感謝您的額外信息! – user3599803