2014-07-08 55 views
3

使用timer_create,我們傳遞一個實時信號給等待select功能的線程。選擇系統偶爾不會失敗EINTR

該信號在線程中被捕獲和處理。基於事實,當信號被捕獲時選擇將被中斷,如果select失敗,我有一些邏輯實現,錯誤號爲EINTR

這在大部分時間都可以正常工作,但偶爾我會注意到select不會被打斷(或某些EINTR情況下的代碼未被執行)。

這有什麼可能的原因?

回答

2

可能是因爲當定時器到期信號被傳送時,您不會在select中等待,因此它不會返回EINTR

如果你想收到EINTR只有當線程被阻塞在select,您可以使用pthread_sigmask阻止的線程信號和使用pselectepoll_pwait而只有等待,將取消阻止信號。這樣,其餘的代碼不需要關心處理EINTR

如果您在進程中有多個線程,請確保您在所有其他線程中阻止該信號,以便只有一個線程獲得該信號。有關更多詳情,請參閱Signal Concepts

一個更優雅的選項(IMO)是避免使用timer_create和延遲,而傳遞到下一個計時器到期的select超時參數(這就是libevent一樣)。但那需要你保持你自己的最小堆定時器。

+0

若要進一步闡述,如果邏輯失敗,我們用sigabrt殺死該進程並獲取核心。從核心看來,該線程在選擇呼叫時被阻止。還有一件事,我們不會立即失敗這個邏輯,我們會等待將近1分鐘,然後再殺死這個進程。 – sony

+0

@ user3816365如果進程中有多個線程,請確保在所有其他線程中都阻止該信號,以便只有一個線程獲得該信號。 http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html –

+0

該信號被該進程中的所有其他線程阻止。 – sony