使用timer_create
,我們傳遞一個實時信號給等待select
功能的線程。選擇系統偶爾不會失敗EINTR
該信號在線程中被捕獲和處理。基於事實,當信號被捕獲時選擇將被中斷,如果select
失敗,我有一些邏輯實現,錯誤號爲EINTR
。
這在大部分時間都可以正常工作,但偶爾我會注意到select
不會被打斷(或某些EINTR
情況下的代碼未被執行)。
這有什麼可能的原因?
使用timer_create
,我們傳遞一個實時信號給等待select
功能的線程。選擇系統偶爾不會失敗EINTR
該信號在線程中被捕獲和處理。基於事實,當信號被捕獲時選擇將被中斷,如果select
失敗,我有一些邏輯實現,錯誤號爲EINTR
。
這在大部分時間都可以正常工作,但偶爾我會注意到select
不會被打斷(或某些EINTR
情況下的代碼未被執行)。
這有什麼可能的原因?
可能是因爲當定時器到期信號被傳送時,您不會在select
中等待,因此它不會返回EINTR
。
如果你想收到EINTR
只有當線程被阻塞在select
,您可以使用pthread_sigmask
阻止的線程信號和使用pselect
或epoll_pwait
而只有等待,將取消阻止信號。這樣,其餘的代碼不需要關心處理EINTR
。
如果您在進程中有多個線程,請確保您在所有其他線程中阻止該信號,以便只有一個線程獲得該信號。有關更多詳情,請參閱Signal Concepts。
一個更優雅的選項(IMO)是避免使用timer_create
和延遲,而傳遞到下一個計時器到期的select
超時參數(這就是libevent一樣)。但那需要你保持你自己的最小堆定時器。
若要進一步闡述,如果邏輯失敗,我們用sigabrt殺死該進程並獲取核心。從核心看來,該線程在選擇呼叫時被阻止。還有一件事,我們不會立即失敗這個邏輯,我們會等待將近1分鐘,然後再殺死這個進程。 – sony
@ user3816365如果進程中有多個線程,請確保在所有其他線程中都阻止該信號,以便只有一個線程獲得該信號。 http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html –
該信號被該進程中的所有其他線程阻止。 – sony