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

Was passiert mit einem Multithread-Linux-Prozess, wenn er ein Signal erhält?

Der Eintrag in POSIX zu "Signal Generation and Delivery" in "Rationale:System Interfaces General Information" sagt

Für einen Prozess generierte Signale werden nur an einen Thread geliefert. Wenn also mehr als ein Thread geeignet ist, ein Signal zu empfangen, muss einer ausgewählt werden. Die Wahl der Threads bleibt vollständig der Implementierung überlassen, um sowohl die größtmögliche Bandbreite an konformen Implementierungen zu ermöglichen als auch Implementierungen die Freiheit zu geben, das Signal an den "einfachst möglichen" Thread zu liefern, falls es Unterschiede in der Einfachheit der Lieferung zwischen verschiedenen Threads geben sollte.

Aus dem signal(7) Handbuch auf einem Linux-System:

Ein Signal kann für einen Prozess als Ganzes generiert (und somit anstehend) werden (z. B. wenn es mit kill(2) gesendet wird). ) oder für einen bestimmten Thread (z. B. sind bestimmte Signale wie SIGSEGV und SIGFPE, die als Folge der Ausführung einer bestimmten Maschinensprachanweisung erzeugt werden, Thread-gerichtet, da Signale, die unter Verwendung von pthread_kill(3) auf einen bestimmten Thread gerichtet sind ). Ein prozessgerichtetes Signal kann an jeden der Threads geliefert werden, bei dem das Signal derzeit nicht blockiert ist. Wenn mehr als einer der Threads das Signal entsperrt hat, dann wählt der Kernel einen beliebigen Thread, an den er das Signal liefert.

Und in pthreads(7) :

Threads haben unterschiedliche alternative Signalstapeleinstellungen. Die alternativen Signalstack-Einstellungen eines neuen Threads werden jedoch von dem Thread kopiert, der ihn erstellt hat, sodass die Threads zunächst einen alternativen Signalstack teilen (behoben in Kernel 2.6.16).

Aus dem pthreads(3) Handbuch auf einem OpenBSD-System (als Beispiel für einen alternativen Ansatz):

Signal-Handler werden normalerweise auf dem Stack des aktuell ausgeführten Threads ausgeführt.

(Mir ist derzeit nicht bekannt, wie dies gehandhabt wird, wenn mehrere Threads gleichzeitig auf einem Computer mit mehreren Prozessoren ausgeführt werden)

Die ältere LinuxThread-Implementierung von POSIX-Threads erlaubte nur, dass bestimmte einzelne Threads von Signalen angesteuert wurden. Ab pthreads(7) auf einem Linux-System:

LinuxThreads unterstützt nicht die Vorstellung von prozessgesteuerten Signalen:Signale können nur an bestimmte Threads gesendet werden.


Als Erweiterung der akzeptierten Antwort gibt es eine praktischere Sichtweise, die ich hier gefunden habe.

Die Essenz ist die folgende:

Signal-Handler sind pro Prozess, aber Signalmasken sind pro Thread.

  1. Wenn wir also einen Signal-Handler (mit signal() oder sigaction()) auf irgendeinem Thread installieren/deinstallieren, wirkt sich das auf alle aus.
  2. Wenn ein Prozess ein Signal erhält, wird der Handler nur auf einem einzigen Thread ausgeführt. Unter diesen wird pseudozufällig dieser Thread ausgewählt, dessen Signalmaske ihn akzeptiert. Meine Experimente zeigen, dass es immer der Thread mit der geringsten PID ist.
  3. Signale, die an einen beliebigen Thread gesendet werden, werden als an den Hauptprozess gesendete Signale betrachtet. Wenn also ein Thread ein Signal erhält, ist es durchaus möglich, dass ein anderer Thread den Handler ausführt. Am besten sehen wir das so, als ob Fäden (gekennzeichnet durch tid s, Thread-IDs) würden als maskierte Prozesse betrachtet (gekennzeichnet durch pid). s) und Signale, die an tid gesendet werden an deren pid weitergeleitet werden .
  4. Für die Ausführung eines Signalhandlers wird in seiner Signalmaske automatisch die angegebene Signalnummer maskiert. Dies dient dazu, die Ausführung eines gestapelten Signal-Handlers in einem Signal-Burst zu verhindern. Dies kann mit dem SA_NODEFER geändert werden Flag des sigaction(...) anrufen.
  5. (3) und (4) ergibt, dass das System im Falle eines Signalbursts die Signalhandler möglichst parallel verteilt.
  6. Allerdings, wenn wir die sigaction mit SA_NODEFER eingerichtet haben , immer derselbe Thread erhält das Signal und sie werden gestapelt .

Linux
  1. Was ist ein Linux-Benutzer?

  2. Wie sieht der Außerbetriebnahmeprozess Ihrer Linux-Serverhardware aus?

  3. Was passiert mit einem geöffneten Datei-Handle unter Linux, wenn die angegebene Datei verschoben oder gelöscht wird

  4. Wie kann ich unter Linux feststellen, welcher Prozess meinem Prozess ein Signal gesendet hat?

  5. Signalbehandlung mit mehreren Threads in Linux

Grundlagen zu Linux-Signalen – Teil I

Was bedeuten unter Linux alle Werte im obersten Befehl?

Was ist die Linux-Prozesstabelle? Woraus besteht es?

Was bedeutet &am Ende eines Linux-Befehls?

Was ist ein gestoppter Prozess unter Linux?

Welche Prozesskiller hat Linux?