Der letzte inhaltliche Teil beschäftigt sich nun mit einigen Feinheiten, die zu Tage treten,
wenn man verschiedene der Konzepte, die in SP vorgestellt wurden, kombiniert.
Und dabei fangen wir zunächst einmal mit Threads und Signalen an.
Denn hier stellt sich die Frage, welcher Thread eigentlich für die Ausführung einer
Signalbehandlung zuständig ist, wenn ein Prozess, der aus mehreren Threads besteht, ein Signal
zugestellt bekommt.
Hier wird tatsächlich unterschieden, da einige Signale direkt an einen einzelnen Thread gerichtet
sein können.
Dies sind zum Beispiel die synchron aufdrehenden Signale, also alle, die durch die unmittelbare
Handlung des Threads selbst zustande kommen, zum Beispiel eben ein Segmentation Fault,
falls auf einen ungültigen Speicherbereich zugegriffen wurde, oder eben solche Signale,
die explizit an einen einzelnen Thread geschickt wurden, in dem die Funktion PThreadKill aufgerufen
wurde.
Die andere Möglichkeit ist, dass ein Signal nicht an einen Thread, sondern an einen Prozess
gerichtet ist.
Das sind all jene Signale, die über den Kills-Systemaufruf erzeugt werden.
Wenn nun also ein Signal geschickt wird, müssen wir ein bisschen schauen.
Entweder das Signal wurde an einen einzelnen Thread geschickt, dann wird dieser für die
Behandlung zuständig sein.
Wenn das Signal jedoch an einen Prozess geschickt wurde, dann ist ein beliebiger Thread aus
dem Prozess für die Bearbeitung des Signals zuständig.
Eine Ausnahme ergibt sich dabei nur, wenn eine Signalmaske gesetzt wurde, denn diese
ist immer Thread-lokal.
Möchte man nun pro Thread eine Signalmaske setzen, so kann man die Funktion PThreadSigMask
verwenden, im Gegensatz zur vorher vorgestellten Funktion SigProcMask.
Mit PThreadSigMask kann die Signalmaske eines einzelnen Threads gesetzt werden.
Dabei muss man aufpassen, dass man innerhalb des selben Programms nicht SigProcMask und
PThreadSigMask vermischt, da hier sonst undefiniertes Verhalten auftreten würde.
Weiterhin ist zu beachten, dass neu erstellte Threads die Signalmaske eben jenes Threads
erben, der sie erzeugt hat.
Wenn nun also ein Thread ein einzelner Signal blockiert, dann wird diesem das jeweilige
Signal nicht zugestellt, auch nicht, wenn es sich dabei um ein prozessweites Signal
handelt.
Stattdessen wird das Signal dann an ein anderes Thread zugestellt, da das Signal nicht blockiert
hat.
Wenn ein Signal auftritt, das an einen einzelnen Thread adressiert ist, dieser aber das Signal
blockiert hat, dann wird dieses solange verzögert, bis die Blockierung aufgehoben ist.
Die nächste Besonderheit, die wir besprechen wollen, tritt immer in der Konstellation
auf, wenn man mehrere Threads hat und gleichzeitig einen Fork ausführen möchte.
Tatsächlich wird bei einem Fork nur das Prozessabbild des aufrufenden Threads geklont.
Das bedeutet also, dass in dem neu erstellten Prozess nur ein Thread existiert, da die anderen
nicht mit übernommen werden.
Als Konsequenz gibt es nun jede Menge Daten, die in einem inkonsistenten Zustand sind.
Zum Beispiel können andere Prozesse während des Forks gerade in einem kritischen Abschnitt
gewesen sein.
Das bedeutet, sie haben zum Beispiel irgendwelche Mootexe gelockt, die sie in dem neu erstellten
Prozess nicht mehr freigeben können.
Also läuft man in dem neu erstellten Prozess Gefahr, in ein Deadlock zu rennen, sobald
man auf eine geteilte Ressource zugreifen möchte, die durch irgendwelche Mittel geschützt
ist.
Zugänglich über
Offener Zugang
Dauer
00:05:46 Min
Aufnahmedatum
2021-01-10
Hochgeladen am
2021-01-10 19:18:37
Sprache
de-DE