1. ホーム
  2. c

[解決済み] POSIXスレッドとシグナル

2023-06-08 06:56:22

質問

POSIXスレッドとPOSIXシグナルがどのように相互作用するかについて、複雑な点を理解しようとしています。特に、私は以下のことに興味があります。

  • シグナルがどのスレッドに配信されるかを制御する最善の方法は何ですか (それが最初の場所で致命的でないと仮定して)。
  • シグナルが到着したことを別のスレッド (実際には忙しいかもしれません) に伝える最良の方法は何でしょうか? (私は、シグナルハンドラから pthread 条件変数を使用することが悪い考えであることをすでに知っています)。
  • シグナルが発生したという情報を他のスレッドに安全に渡すにはどうしたらよいですか? これはシグナル ハンドラで起こる必要がありますか? (私は一般的に他のスレッドを殺したくありません。私ははるかに微妙なアプローチを必要とします。)

私がこれを望む理由についての参考のために、私は TclX パッケージをスレッドをサポートするように変換する方法、またはそれを分割して少なくともいくつかの有用な部分をスレッドをサポートするようにする方法を研究しています。シグナルは、特に関心のあるこれらの部分の 1 つです。

どのように解決するのですか?

<ブロッククオート
  • シグナルがどのスレッドに配信されるかを制御する最良の方法は何ですか? に配信されるかを制御する最良の方法は何ですか?

zoli2k が示したように、処理させたいすべてのシグナルを処理する単一スレッド(または特定のシグナルを担当するスレッドのセット)を明示的に指名するのは良い手法です。

  • 他のスレッド (実際にはビジー状態かもしれません) にシグナルが到着したことを伝える最良の方法は何でしょうか? シグナルが到着したことを伝える最良の方法は何ですか?
  • シグナルが発生したという情報を他のスレッドに安全に渡すにはどうしたらよいでしょうか? を他のスレッドに安全に渡すことができますか?これはシグナルハンドラで起こる必要があるのでしょうか?

ベストとは言いませんが、私の推奨は以下の通りです。

の中にあるすべての希望するシグナルをブロックする。 main でブロックし、すべてのスレッドがそのシグナルマスクを受け継ぐようにします。 そして、シグナルを受け取る特別なスレッドをシグナル駆動のイベント ループとして作り、新しく到着したシグナルを 他のスレッド内通信 .

これを行う最も簡単な方法は、スレッドがループ内でシグナルを受け取るようにすることです。 sigwaitinfo または sigtimedwait . 次にスレッドはシグナルを何らかの方法で変換します。 pthread_cond_t をブロードキャストしたり、より多くの I/O で他のスレッドを目覚めさせたり、アプリケーション固有のスレッドセーフキューにコマンドをエンキューしたりと、さまざまな方法で変換します。

代わりに、特別なスレッドはシグナルハンドラに配信されるシグナルを許可し、シグナルを処理する準備ができたときだけ配信のためにマスクを外すことができます。 (ハンドラーを介したシグナル配信は sigwait ファミリーを介してシグナルを受け入れるよりも、ハンドラを介したシグナル配信はエラーが発生しやすい傾向がある)。 この場合、受信側のシグナルハンドラは単純で非同期なシグナルセーフのアクションを実行します。 sig_atomic_t フラグを設定し sigaddset(&signals_i_have_seen_recently, latest_sig) , write () バイトをノンブロッキングの セルフパイプ など。 その後、マスクされたメインループに戻り、スレッドは上記のように他のスレッドにシグナルの受信を伝達します。

( UPDATED @caf さんのご指摘の通り sigwait のアプローチの方が優れていると指摘しています)。