GNU/Linux >> Linux の 問題 >  >> Linux

Linux での複数スレッドによるシグナル処理

pthreads(7) POSIX.1 では、プロセス内のすべてのスレッドが以下を含む属性を共有する必要があると説明しています:

  • 信号処理

POSIX.1 では、いくつかの属性を区別する必要もあります 以下を含む各スレッド:

  • シグナルマスク (pthread_sigmask(3) )

  • 代替信号スタック (sigaltstack(2) )

Linux カーネルの complete_signal ルーチンには次のコード ブロックがあります -- コメントは非常に役に立ちます:

/*
 * Now find a thread we can wake up to take the signal off the queue.
 *
 * If the main thread wants the signal, it gets first crack.
 * Probably the least surprising to the average bear.
 */
if (wants_signal(sig, p))
        t = p;
else if (!group || thread_group_empty(p))
        /*
         * There is just one thread and it does not need to be woken.
         * It will dequeue unblocked signals before it runs again.
         */
        return;
else {
        /*
         * Otherwise try to find a suitable thread.
         */
        t = signal->curr_target;
        while (!wants_signal(sig, t)) {
                t = next_thread(t);
                if (t == signal->curr_target)
                        /*
                         * No thread needs to be woken.
                         * Any eligible threads will see
                         * the signal in the queue soon.
                         */
                        return;
        }
        signal->curr_target = t;
}

/*
 * Found a killable thread.  If the signal will be fatal,
 * then start taking the whole group down immediately.
 */
if (sig_fatal(p, sig) &&
    !(signal->flags & SIGNAL_GROUP_EXIT) &&
    !sigismember(&t->real_blocked, sig) &&
    (sig == SIGKILL || !p->ptrace)) {
        /*
         * This signal will be fatal to the whole group.
         */

あなた シグナルが配信される場所を担当します:

プロセスがシグナルの性質を SIG_IGN に設定している場合 または SIG_DFL の場合、シグナルはすべてのスレッドで無視されます (またはデフォルト -- kill、core、または ignore)。

プロセスがシグナルの性質を特定のハンドラー ルーチンに設定している場合、pthread_sigmask(3) を使用して特定のスレッド シグナル マスクを操作することにより、どのスレッドがシグナルを受信するかを制御できます。 .それらすべてを管理する 1 つのスレッドを指定するか、シグナルごとに 1 つのスレッドを作成するか、特定のシグナルに対してこれらのオプションを任意に組み合わせて作成するか、メイン スレッドにシグナルを配信する Linux カーネルの現在のデフォルト動作に依存することができます。

ただし、一部のシグナルは signal(7) に従って特別です。 マニュアルページ:

<ブロック引用>

シグナルは、プロセス全体 (たとえば、kill(2) を使用して送信される場合) または特定のスレッド (たとえば、SIGSEGV や SIGFPE などの特定のシグナルの実行の結果として生成される) に対して生成される (したがって保留中) 場合があります。 pthread_kill(3) を使用して特定のスレッドを対象とするシグナルと同様に、特定の機械語命令はスレッド向けです。プロセス指向のシグナルは、現在シグナルがブロックされていないスレッドのいずれかに配信される可能性があります。複数のスレッドでシグナルのブロックが解除されている場合、カーネルはシグナルを配信する任意のスレッドを選択します。


これは、使用している Linux カーネルのバージョンによって若干異なります。

2.6 posix スレッドを想定し、SIGTERM または SIGHUP を送信する OS について話している場合、シグナルはプロセスに送信され、ルートスレッドによって受信および処理されます。 POSIX スレッドを使用すると、SIGTERM を個々のスレッドに送信することもできますが、OS がシグナルをプロセスに送信したときに何が起こるかについて尋ねているのではないかと思います。

2.6 では、SIGTERM は子スレッドを「正常に」終了させますが、2.4 では、子スレッドは不確定な状態のままでした。


Linux
  1. Linux –タスクセットとの実行中のプロセスアフィニティの設定が失敗しますか?

  2. Linux でスレッドを作成する方法 (C サンプル プログラムを使用)

  3. Linuxでスレッドに名前を付ける方法は?

  1. ターミネーターを使用して複数のSSHセッションにコマンドを送信する

  2. LinuxでのJQコマンドと例

  3. Linux カーネル スレッドは本当にカーネル プロセスですか?

  1. UNIX/Linux シグナル処理:SIGEV_THREAD

  2. fopen() は Linux のスレッドセーフ関数ですか?

  3. Linux での Ctrl + C 割り込みイベント処理