2017-08-29 6 views
0

pthread条件変数を待っていますが、SIGUSR1(またはその他の信号)を受け取ったときにpthread_cond_signalや偽のウェイクアップが原因でシグナルが待っているのを待って停止するのを検出しません。これどうやってするの?pthread条件変数またはシグナルを待つ方法はありますか?

+0

@alk pthread_cond_waitとpthread_cond_timedwaitのmanページには、「これらの関数は[EINTR]のエラーコードを返さないものとします。 – tbodt

+0

ヘルパースレッドを使用する必要があるようです(シグナルをキャッチするか、条件変数を待つために)。実際には、すべてのレースを終了するには、2つのヘルパースレッドとセマフォを使用しなければならず、元のスレッドがセマフォを待機している必要があります。 –

答えて

1

pthreadsプログラムで信号を処理する信頼できる方法は、すべてのスレッドで処理したいすべてのシグナルをマスクし、sigwaitinfo()(またはsigtimedwait())を呼び出してループする専用シグナル処理スレッドを作成することです。

信号処理スレッドは通常のミューテックス保護された共有変数とpthread_cond_signal()/pthread_cond_broadcast()ウェークアップを使用して、受け取った信号について他のスレッドに知らせることができます。

あなたの例では、専用信号処理スレッドは、SIGUSR1が受信されたことを示す(mutex保護された)フラグを設定して、スレッドが待機している条件変数を通知できます。待ちスレッドは、ループ内の他の共有状態に加えて、信号フラグを確認する必要があります。ループは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

関連する問題