據this paragraph,下面有問題:什麼是暫停()的問題?
/* usr_interrupt is set by the signal handler. */
if (!usr_interrupt)
pause();
/* Do work once the signal arrives. */
...
並應使用sigsuspend
代替。
但我還沒有看到這個問題是pause
什麼,以及如何解決sigsuspend
它,
任何人都可以更詳細解釋一下嗎?
據this paragraph,下面有問題:什麼是暫停()的問題?
/* usr_interrupt is set by the signal handler. */
if (!usr_interrupt)
pause();
/* Do work once the signal arrives. */
...
並應使用sigsuspend
代替。
但我還沒有看到這個問題是pause
什麼,以及如何解決sigsuspend
它,
任何人都可以更詳細解釋一下嗎?
讓我們看看會發生什麼,當信號到達您之前已經檢查usr_interrupt
但後打電話pause
:
main thread signal handler ----------- -------------- if (!usr_interrupt) // this is true // signal kicks up handler usr_interrupt = 1; // handler finishes pause(); // will wait for signal
你可以,你已經錯過了的信號的情況下看到的。非常重要的是,如果沒有進一步的信號傳入,因爲你的程序將會從永遠不會動作。這就是所謂的競賽條件。現在讓我們看看與sigsuspend
會發生什麼:
main thread signal handler ----------- -------------- // set up to delay signal. sigemptyset (&mask); sigaddset (&mask, SIGUSR1); // this will delay (block) signal. // possibly do this first if USR1 // may be blocked already (check!): // sigprocmask (SIG_UNBLOCK, &mask, &old); sigprocmask (SIG_BLOCK, &mask, &old); if (!usr_interrupt) // signal arrives, delayed. // unblock signal/wait (atomically). sigsuspend (&old); // delayed handler start. usr_interrupt = 1; // handler finishes. // sigsuspend returns, clean up. sigprocmask (SIG_UNBLOCK, &mask, NULL);
在這種情況下,沒有競爭條件,因爲信號被延遲,直到主線程是準備好了。
這是一個典型的競賽條件。
Main | Signal handler --------------------|----------------------- // at this point, | // no signal has | // arrived, so we | // enter the if | | if (!usr_interrupt) | | {signal arrives...} | usr_interrupt = 1; | {...handler finishes} pause(); | | // uh-oh, we missed | // the signal! |
即日起至下一個信號到達pause()
不會得到暢通(這取決於程序可能永遠不會發生)。
如果信號也被「老」封鎖了怎麼辦? – wireshark 2011-06-13 08:51:01
@wireshark:如果你設置不正確,那麼它將無法工作。但是對於所有事情都是如此,所以我不確定你的觀點是什麼。如果您想確保設置正確,請先解鎖USR1。 – paxdiablo 2011-06-13 08:54:05
你知道gdb的內部信號處理嗎?希望你知道我以前的問題的答案? http://stackoverflow.com/questions/6301130/sigint-not-trapped-while-debugging-nginx-with-gdb – wireshark 2011-06-13 09:00:16