6

マスター スレッドといくつかのワーカー スレッドを使用してプログラムを作成しており、シグナル処理を正しく行いたいと考えています。私の問題は次のとおりです。

マスタースレッドが開始し、すべての割り当てを行います

マスター スレッドが SIGINT シグナル ハンドラを設定する

マスター スレッドはワーカー スレッドを開始します。ワーカー スレッドは特別なクリーンアップを必要としませんが、システム コールまたはセマフォでスリープ状態になる可能性があります。

SIGINT が受信されると、それを受信するスレッドは 1 つだけであると理解しています。そのため、スレッドがシステム コールまたはセマフォでスリープしている場合、それらは起動されず、ワーカー スレッドに pthread_join できず、マスター スレッドで必要なすべてのクリーンアップを実行できません。

次のシグナル ハンドラーで問題を解決できますか?

void term(int sig)
{
    g_do_cleanup = 1;
    pthread_kill(worker_1_id, some_other_signal);
    ...
    pthread_kill(worker_2_id, some_other_signal);
}

私が期待しているのは、SIGINT を受信すると、すべてのスレッドが別のシグナルで通知され、ブロッキング呼び出しから抜け出し、g_do_cleanupフラグを確認して正常に終了することです。

これを適切に行う方法についてのコメントやリンクは大歓迎です。

編集:特定の条件で待機している複数のスレッドをウェイクアップする方法を探しているわけではないので、 pthread_cond_signal アプローチが探しているものではないと思います。私が欲しいのは:

  • ブロッキング呼び出しでブロックされたすべてのスレッドがこれらの呼び出しから戻る方法を見つけます。
  • または、メインのスレッドを除くすべてのスレッドを強制終了します。
4

3 に答える 3

4

これは、メイン アプリ スレッドで通常行うことです。


/* before starting other threads */
sigset_t sigs;
sigemptyset( &sigs );
sigaddset( &sigs, SIGTERM );
sigaddset( &sigs, SIGINT );
/* add other signals to handle */
if ( pthread_sigmask( SIG_BLOCK, &sigs, 0 )) { /* handle error */ }
/* can start threads now */
...
/* in the main event loop */
siginfo_t info;
if ( sigwaitinfo( &sigs, &info ) == -1 ) { /* handle error */ }
switch( info.si_signo )
{
  case SIGTERM:
  case SIGINT: /* raise shutdown event */ break;
  default: /* other actions - log rotation, etc. */
}
...

このようにして、シグナルは通常のアプリケーション イベントになります。特別なシグナル コンテキストの制限などはありsigtimedwaitません。BSD の派生物ではサポートされていませんが、タイムアウトを使用して待機することもできます。

于 2009-05-28T02:31:38.403 に答える
2

あなたが望むのは pthread 条件変数のように思えます。そのため、マスタースレッドから 1 つの「イベント」を鳴らすことで、任意の数の複数のスレッドをウェイクアップできます。

詳細については、 PTHREAD_COND_DESTROYおよびPTHREAD_COND_BROADCASTのマニュアル ページを参照してください。

于 2009-05-27T15:09:17.907 に答える
1

あなたの計画はうまくいくようです。1つのスレッドにシステム信号の処理を強制しています。pthread-sigmask()を使用して、ワーカースレッドのsome-other-signal以外のシグナルをマスクする必要があります。

マスターではなく、プロセス信号を処理するために別のスレッドを使用すると思います。シグナルハンドラーの実行を待機している間、セマフォやsigwait()などで永久に待機させます。pthread-killコードをシグナルハンドラーの外に移動します。スイッチを設定し、シグナル待機スレッドにother_signalをワーカースレッドに送信させて終了させます。

于 2009-05-27T20:06:40.053 に答える