Kann es zwischen signalfd und sigaction ein Wettrennen geben?

8

Die klassische Methode, einen Handler für ein bestimmtes Signal anzugeben, ist via sigaction . Linux stellt zusätzlich die signalfd -Funktionalität zur Verfügung, wo wir Signale mit einem Dateideskriptor verbinden und dann select / (e) poll auf diesen Deskriptor anwenden können, was perfekt zum Konzept vieler ereignisschleifengesteuerter Systeme passt.

Ich frage mich, was passiert, wenn beide Mechanismen kollidieren. Kann es Rassenbedingungen geben? Auf der Manpage von signalfd ( Ссылка ) lesen wir:

  

Normalerweise die Menge der über den Dateideskriptor zu empfangenden Signale   sollte mit sigprocmask (2) blockiert werden, um die Signale zu verhindern   entsprechend ihren Standardeinstellungen behandelt.

Also heißt es "normal" wir benutzen die Signalmaske, um zu verhindern, dass der (Standard) Handler ein Signal verarbeitet. Es besagt nicht, dass wir dieses Signal blockieren müssen, wenn wir einen Dateideskriptor damit verbunden haben. Leider gibt die man-Seite nicht an, was passiert, wenn wir das Signal nicht blockieren.

Das sieht nach schlecht definiertem Verhalten aus. Ich glaube nicht, dass dies wirklich nicht klar definiert ist und frage mich, ob jemand hier ich weiß, wo ich eine detaillierte Spezifikation darüber finden kann, wie sich das System verhalten soll oder ii ) wie es sich verhält.

Was mich besonders interessiert, ist diese Reihenfolge der Ausführung:

  1. signalfd für ein bestimmtes Signal, einschließlich Blockierung dieses Signals
  2. Entsperrung dieses Signals
  3. sigaction für dieses Signal (Standard-Handler oder benutzerdefinierter Handler)

Ist dies ein undefiniertes Verhalten oder gibt es einen Standard / eine Spezifikation für das, was passieren muss? Hat der Handler immer Vorrang vor dem Dateideskriptor? Wird der Handler und aufgerufen, löst der Dateideskriptor ein Ereignis aus? Ändert die Einstellung sigaction die Signalmaske, Rendering Schritt (2) unnötig?

Ich könnte versuchen, das tatsächliche Verhalten aus systematischen Tests mit tatsächlichem Code abzuleiten. Ich bevorzuge natürlich eine detaillierte Dokumentation und denke, dass ich nicht in der Lage war, die richtige Referenz selbst zu finden.

    
Jan-Philip Gehrcke 26.11.2013, 21:14
quelle

1 Antwort

11

signalfd verhält sich genauso wie sigwaitinfo , außer dass Sie über einen Dateideskriptor auf die Informationen zugreifen können. Dies bedeutet, dass ein signalfd Signale synchron empfängt und Signalhandler (oder die Standarddisposition) zuerst .

Quelle: TLPI Kapitel 22.10 und 22.11 (M. Kerrisk).

Das Verhalten ist gut definiert, aber nicht unbedingt das, was man erwarten würde, und die Manpage ist ziemlich schlecht formuliert. Das Sagen von "normal ... sollte" deutet darauf hin, dass Sie das entweder nicht wirklich müssen, oder schlimmer noch, dass der Autor sich nicht ganz sicher ist.
Wenn du willst, dass es "richtig" funktioniert, d. H. Wie du es normalerweise erwartest (siehe, ich habe auch "normal" verwendet), musst du die Signale blockieren. Andernfalls wird das Signal über den Dateideskriptor verfügbar sein, aber ein Handler wird immer noch zuerst aufgerufen (was völlig legitim ist, aber die meisten Leute würden wahrscheinlich dieses "seltsame Verhalten" betrachten).

Somit gibt es zwei verschiedene Rassenbedingungen. Eine Bedingung ist die, nach der Sie fragen, aber obwohl das Verhalten ein bisschen unerwartet ist, ist es gut definiert und (irgendwie) dokumentiert, und wenn Sie darüber nachdenken, dann ist es nicht unbedingt eine Race Condition. Es ist vielmehr eine Art "Doppellieferung".
Die andere Race-Bedingung ist die Möglichkeit, dass ein Signal ankommt, nachdem Sie die signalfd erstellt haben, aber bevor Sie das Signal blockiert haben. Es ist sehr unwahrscheinlich, aber im Prinzip könnte dies passieren. Zum Glück ist die Lösung einfach, Sie können das Signal zuerst blockieren und dann den Dateideskriptor erstellen (der dann sofort bereit ist, wenn ein Signal dazwischen kommt).

Die Reihenfolge der Befehle, die Sie benannt haben (Dateideskriptor erstellen, Blockade aufheben, dann sigaction ) hat eine ähnliche Wettlaufbedingung. Sie sollten zuerst einen Handler installieren und dann die Blockierung aufheben, oder ein Signal kann geliefert werden, bevor der Handler da ist. Aber das ist unabhängig von signalfd . Der Dateideskriptor könnte in jedem Fall weiterhin zum Lesen des Signals verwendet werden, aber die Standarddisposition könnte den Prozess abbrechen, wenn ein Signal zwischen Entsperren und Installieren des Handlers eintrifft.

    
Damon 26.11.2013, 23:20
quelle

Tags und Links