6

プロデューサー スレッドとコンシューマー スレッドを使用する Linux アプリに取り組んでいます。これはかなり成熟したアプリであり、必要以上にアーキテクチャを変更したくありません。

プロデューサ スレッドとコンシューマ スレッドは、待機可能なキューを介してリンクされます。これは、条件変数とミューテックスとともに std::queue を介して実装されるクラスです。

ここで、消費者スレッドが子プロセスを fork/exec できるようにし、子プロセスが終了するか、待機可能なキューが空でなくなるまで待機できるようにしたいと考えています。待機可能なキューが空でない場合は、子プロセスを強制終了する必要があります。編集:子プロセスは、変更できないサードパーティのアプリです。

1 つの可能性は、子プロセスが終了したときに条件変数で pthread_cond_signal() を呼び出すことですが、それを実現するにはどうすればよいでしょうか? man ページには pthread_cond_signal() はシグナル ハンドラからは使用できないと記載されている ため、SIGCHLD のハンドラを少なくとも直接使用することはできません。

考えられる 1 つの方法は、子プロセスを生成してからスレッドを開始してブロックしている waitpid() を実行し、最後に pthread_cond_signal() を実行することです。しかし、これは少し不格好に思えます: pid を監視するためだけに、本当にスレッドを生成する必要がありますか?

waitpid と select/poll/epoll を混在させるには、Self Pipe Trickがあります。waitpid と条件変数を混在させるのに相当するものはありますか?

注 1:一部の実装では、SIGCHLD は条件変数の待機関数を中断します。これは移植性がなく、可能であれば、この動作に依存したくありません。

注 2:条件変数は待機可能なキュー クラス内にカプセル化されているため、このクラスを拡張して、アプリがミューテックスに通知できるようにする必要があります。これは、私の質問で説明した些細な実装の詳細です。

4

1 に答える 1

1

多分これはうまくいくかもしれませんが、私にはわかりません:

待機可能なキューに登録され、状態の変化を示すために待機可能なキュー自体が独自のロックを変更するたびにロック/変更/ロック解除されるセマフォを作成します。セマフォを保持している間に、独自のミューテックスを変更する必要があります。

のシグナル ハンドラを実装しますSIGCHLD。これにより、サード パーティのアプリが終了するときにセマフォのロック/変更/ロック解除が実行され、そうでない場合は何も実行されません。

上記のケースでは、セマフォのロックを取得したい場合、 1を待ってセマフォを (1 つのセマフォ操作として) 増加させ、次に作業を行い、セマフォを0に変更します ( 2 ずつ減少)。待機スレッドのロックを解除します。こうすることで、キューやサードパーティ製アプリから 2 回連続してロックが成功することはありません。

実際のスレッドでは、サードパーティのアプリが終了するか、待機可能なキューのいずれかを待機する必要があります。基本的に、0を待機している間、同じセマフォのロックを待機させます(他の待機者がいる場合は、それをデクリメントします)。 0)。ロックが取得された場合は、待機可能なキューのミューテックスが解放されているかどうかを確認します。そうでない場合は、サードパーティのアプリが終了したことがわかります。作業を実行してから、セマフォをインクリメントして1に変更し、キューとサードパーティ アプリのセマフォを再度ロック解除します。

semop(2)-lock 呼び出しはシグナル ハンドラーによって中断される可能性があるため、ロックの試行をチェックしてEINTRループする必要があります。

これは、シグナルハンドラーが実行を終了することが保証されている場合におそらく機能します(これはそうであると思います)。

于 2012-09-06T13:18:20.370 に答える