6

シグナルハンドラから共有データにアクセスするのが良いかどうか知りたいです。つまり、単一プロセスのマルチプロセスシステムとマルチスレッドシステムのシナリオを考えてみてください。マルチプロセスシステムでは、プロセスに特定の信号を処理させ、プロセスによって特定の共有変数またはメモリを更新させるとします。シグナルハンドラ自体からそれを行うことはできますか?

ただし、pthreadを使用するスレッドの場合、それは実行可能ではないと思います。http://maxim.int.ru/bookshelf/PthreadsProgram/htm/r_40.html。この記事で述べたように、彼らはそれが非同期信号に対して安全ではないと述べており、そのためにsigwaitを使用することを提案しています。私はそれが非同期信号安全ではない理由ではありません。つまり、私はスレッドによってシグナルを処理し、シグナルハンドラルーティングに参加しています。共有メモリのロックを取得して更新します。その間に、同じタイプの別のシグナルが到着し、それを処理する別のスレッドがシグナルハンドラーを再度実行します。ここで、シグナルハンドラーはプロセスと同じですが、複数回呼び出されます。2回目は、ロックを確認できず、データを更新/上書きします。これは、共有データを使用するマルチスレッド信号ハンドラーの問題ですか。

私は少し混乱しています。マルチプロセスシステムでは、各プロセスのシグナルハンドラーのコピーがあります。しかし、マルチスレッドシステムでは、複数のスレッドで使用されるシグナルハンドラーの単一のコピーがありますね。したがって、同じタイプの複数のシグナルが到着し、それを処理する2つのスレッドがある場合、両方が同じハンドラーコードを実行しようとしますか?それはどのように適合しますか?

4

1 に答える 1

6

あなたが参照している記事を読み、「シグナル ハンドラーのスレッド」セクションで興味深い情報を見つけました。そのセクションには、シグナル ハンドラー内から実行できる Posix 関数呼び出しのリストがあることがわかります。その後、そのリストのすぐ後に、次のことが言及されています。

しかし、Pthreads 呼び出しはどこにあるのでしょうか? それらはこれらのリストのどちらにもありません! 実際、Pthreads 標準では、関数がシグナル ハンドラから呼び出された場合、すべての Pthreads 関数の動作は未定義であると規定されています。ハンドラーが、他のスレッドと共有されているデータ (バッファー、フラグ、または状態変数) を操作する必要がある場合、それはうまくいきません。Pthreads ミューテックスと条件変数の同期呼び出しは立ち入り禁止です。

最後の文に注意してください:「Pthreads ミューテックスと条件変数の同期呼び出しは立ち入り禁止です」

シグナルハンドラから呼び出すことができる前述の関数は、次のように説明されています。

これらの関数には、再入可能性と呼ばれる特別なプロパティがあり、プロセスがこれらの関数を同時に複数回呼び出すことができます。

pthread 同期関数には、再入可能性として知られる特別なプロパティがないため、これらの関数 (たとえば、pthread_mutex_lock()) が着信シグナルによって中断された場合、動作は「安全」ではないと思います。

アプリケーションが呼び出しpthread_mutex_lock(&theMutex)を行い、まさにその瞬間 (つまり、pthread_mutex_lock() 関数内) にシグナルが到着したとします。シグナル ハンドラが も呼び出すpthread_mutex_lock(&theMutex)場合、前の pthread 呼び出しが終了していない可能性があるため、どの pthread_mutex_lock() 呼び出しがロックを取得するかは保証されません。したがって、結果として生じる動作は未定義/不確定になります。

特定のスレッドから sigwait() を呼び出すと、重要なnon-reentrancy関数呼び出しが中断されないことが保証されるため、pthread 同期関数の呼び出しを「安全」にすることができると思います。

于 2012-09-16T15:19:35.023 に答える