2017-08-29 69 views
0

我想等待一個pthread條件變量,但是當我得到一個SIGUSR1(或任何其他信號)時,我想停止等待並檢測它是否因信號而停止等待,而不是因爲pthread_cond_signal或虛假喚醒。我怎樣才能做到這一點?如何等待pthread條件變量或信號?

+0

@alk pthread_cond_wait和pthread_cond_timedwait的手冊頁顯示「這些函數不會返回[EINTR]的錯誤代碼。」 – tbodt

+0

看起來您可能需要使用助手線程(用於捕獲信號或等待條件變量)。實際上,要關閉所有的比賽,你可能不得不使用兩個助手線程和一個信號量,而原始線程正在等待信號量。 –

回答

1

在pthreads程序中處理信號的可靠方法是屏蔽所有希望在每個線程中處理的信號,並創建一個專用信號處理線程,該線程圍繞調用sigwaitinfo()(或sigtimedwait())進行循環。

然後信號處理線程可以使用普通的受互斥體保護的共享變量和喚醒通知其他線程有關接收到的信號。

在您的示例中,專用信號處理線程可能會設置一個表示已收到SIGUSR1的(互斥鎖保護)標誌,然後發出線程正在等待的條件變量。等待的線程只需要檢查信號標誌,除了在pthread_cond_wait()周圍的循環中的其他共享狀態。

+0

該線程可能正在等待程序中的任何條件變量,所以我不能僅僅通過信號處理程序發出線程正在等待的條件變量的信號。我可以在pthread_cond_wait中使用一個包裝函數,該函數將條件保存在信號處理程序的線程本地中,但這很難避免競爭條件的影響。如果信號到達並且處理程序在存儲線程本地和開始等待之間運行pthread_cond_broadcast。 – tbodt

+0

@tbodt:POSIX說[pthread_cond_signal()'在信號處理程序中不安全](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_signal.html)。 –

+0

它應該總是清楚你的線程可以等待哪些條件變量。如果存在多種可能性,則可以將它們全部發信號(無論如何,條件變量可能會虛假地喚醒,所以始終可以安全地向它們發送不必要的信號)。 (另外,這裏的想法並不是從信號處理程序調用'pthread_cond_broadcast()',而是從'sigwaitinfo()'返回並出隊信號之後在普通線程上下文中運行的信號處理線程中調用。 – caf