GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Signalbehandlung mit mehreren Threads in Linux

pthreads(7) beschreibt, dass POSIX.1 alle Threads in einem Prozess Share-Attribute benötigt, einschließlich:

  • Signaldispositionen

POSIX.1 erfordert auch, dass einige Attribute eindeutig sind für jeden Thread, einschließlich:

  • Signalmaske (pthread_sigmask(3) )

  • alternativer Signalstapel (sigaltstack(2) )

complete_signal des Linux-Kernels Routine hat den folgenden Codeblock -- die Kommentare sind sehr nützlich:

/*
 * 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.
         */

Sie sehen also Sie sind dafür verantwortlich, wohin die Signale geliefert werden:

Wenn Ihr Prozess die Disposition eines Signals auf SIG_IGN gesetzt hat oder SIG_DFL , dann wird das Signal für alle Threads ignoriert (oder standardmäßig -- kill, core oderignore).

Wenn Ihr Prozess die Disposition eines Signals auf eine bestimmte Behandlungsroutine festgelegt hat, können Sie steuern, welcher Thread die Signale empfängt, indem Sie bestimmte Thread-Signalmasken mit pthread_sigmask(3) manipulieren . Sie können einen Thread ernennen, um sie alle zu verwalten, oder einen Thread pro Signal erstellen, oder eine beliebige Mischung dieser Optionen für bestimmte Signale, oder Sie verlassen sich auf das aktuelle Standardverhalten des Linux-Kernels, das Signal an den Haupt-Thread zu liefern.

Einige Signale sind jedoch speziell gemäß signal(7) Manpage:

Ein Signal kann für einen Prozess als Ganzes (z. B. wenn es mit kill(2) gesendet wird) oder für einen bestimmten Thread (z. B. bestimmte Signale wie SIGSEGV und SIGFPE, die als Folge der Ausführung von a generiert werden) generiert (und somit anstehend) werden spezifische maschinensprachliche Anweisungen sind Thread-gerichtet, ebenso wie Signale, die mit pthread_kill(3) auf einen bestimmten Thread abzielen. Ein prozessgerichtetes Signal kann an jeden der Threads geliefert werden, der derzeit das Signal nicht blockiert hat. Wenn mehr als einer der Threads das Signal nicht blockiert hat, dann wählt der Kernel einen beliebigen Thread aus, an den das Signal geliefert werden soll.


Dies ist leicht nuanciert, je nachdem, welche Version des Linux-Kernels Sie verwenden.

Unter der Annahme von 2.6 Posix-Threads und wenn Sie über das Betriebssystem sprechen, das SIGTERM oder SIGHUP sendet, wird das Signal an den Prozess gesendet, der vom Root-Thread empfangen und verarbeitet wird. Mit POSIX-Threads können Sie SIGTERM auch an einzelne Threads senden, aber ich vermute, Sie fragen danach, was passiert, wenn das Betriebssystem das Signal an den Prozess sendet.

In 2.6 bewirkt SIGTERM, dass untergeordnete Threads "sauber" beendet werden, während in 2.4 untergeordnete Threads in einem unbestimmten Zustand gelassen wurden.


Linux
  1. JQ-Befehl in Linux mit Beispielen

  2. Linux – Festlegen der laufenden Prozessaffinität mit Taskset schlägt fehl?

  3. So erstellen Sie Threads in Linux (mit einem C-Beispielprogramm)

  4. Wie benenne ich einen Thread in Linux?

  5. Ist fopen() eine threadsichere Funktion in Linux?

Installieren Sie Linux mit LVM

Ersetzen Sie unter Linux du durch Staub

wc Linux-Befehl mit Beispielen

Linux-IP-Befehl mit Beispielen

15 Linux-PS-Befehl mit Beispielen

So verwalten Sie mehrere Java-Versionen mit jEnv unter Linux