2011-08-03 11 views
3

2つのスレッドth1、th2を持つデーモンがあります。 th2はread(2)を使用してソケットを読み取ります。2つの結果のSIGTERMを処理する

SIGTERMでデーモンを終了すると、th1が信号を捕捉して処理し(終了フラグを設定します)、デーモンデストラクタが呼び出された後、pthread_kill(th2, SIGTERM)を呼び出します。しかし、2番目のスレッドはSIGTERMを受信しないので、ソケットはデータを受信して​​終了フラグが設定されているので、実行を終了します(read()から出てきます)。

私がpthread_kill(th2, SIGUSR2)と、そしてpthread_kill(th2, SIGTERM)を呼び出すと、すべてが正しく終了します。したがって、UNIXは結果的に同一の信号を送信することはできないようです。

この動作はオペレーティングシステムによって異なりますか?指定されたスレッドが別のスレッドからSIGTERMを受け取ることを保証できますか?

+1

適切なプログラミング言語のタグ、c、C++、またはyourLanguageHereを含めると、より多くの「目」を得ることができます。がんばろう。 – shellter

+2

ありがとうございました、タグを追加しました。私はUNIXがCを意味すると仮定した) – vissi

+2

@vissi:それは間違っている。あなたはあなたが働いている言語のタグだけを含めるべきです。あなたの質問が相互運用性に関係しない限り、1つの言語にのみタグを付けるべきです。 – Puppy

答えて

5

Unixは、シグナルがあまりにも近くに送信された場合、またはすでに保留中のシグナルが配信される前に追加のシグナルがプロセスに送信された場合でも、複数のシグナルをプロセスに送信できます。単一の信号イベント。

pthread_kill()は、処理される特定のスレッドにシグナルを送信しますが、シグナルの実際の処理にはグローバルな影響があります(シグナルハンドラはスレッドごとではなく、プロセスごとです)。

read()が有効なキャンセルポイントであるため、pthread_cancel()を明示的に呼び出して調べることもできます。必要に応じて、取り消しハンドラを追加するだけでなく、取り消し可能でない関数を使用している場合にスレッドのキャンセル状態をブロックすることもできます。 pthread_cancel()hereの使用に関するヒントを読むことができます。

+0

'sigaction()'とSA_SIGINFOは、POSIXのリアルタイムシグナルキューイングの振る舞いとはまったく直交しています。リアルタイムのセマンティクスを「有効にする」と言うのは間違いです。さらに、これらのセマンティクスが実行時に有効になることを示唆するのは間違いです。リアルタイムシグナル(SIGRTMIN .. SIGRTMAX)は常にキューに入れられますが、標準シグナルはキューに入れません。 – pilcrow

+0

これは私の混乱が起こった場所です(実装されているのではなく、私はLinuxで推測しています)、標準のように見えます'sigaction()'を使って標準シグナルタイプにSA_SIGINFOを設定した場合、シグナルはリアルタイムシグナルに加えてキューに入れられます。これを明確にしてくれてありがとう...私は私の答えを更新します。 – Jason

1

比較的古くて効果的なアプローチは、select()とパイプを使用してシグナルをすべてのスレッドに再ディスパッチすることです。 (ブロッキングハンドルでパイプの読み取りハンドルを選択()します)。

関連する問題