Sie können nicht darauf vertrauen, dass jedes gesendete Signal zugestellt wird. Beispielsweise "verschmilzt" der Linux-Kernel SIGCHLD, wenn ein Prozess bei der Verarbeitung von SIGCHLD aus einem verlassenen untergeordneten Prozess lange dauert.
Um einen anderen Teil Ihrer Frage zu beantworten, werden Signale im Kernel "in die Warteschlange gestellt", wenn mehrere verschiedene Signale in einem zu kurzen Intervall eintreffen.
Sie sollten verwenden sigaction()
, um den Signalhandler mit dem sa_sigaction
Mitglied von einzurichten und siginfo_t
das sa_mask
Mitglied des siginfo_t
Arguments sorgfältig festzulegen. Ich denke, dies bedeutet, zumindest alle "asynchronen" Signale zu maskieren. Laut der Manpage für Linux sigaction()
maskieren Sie auch das Signal, das verarbeitet wird. Ich denke, Sie sollten das sa_flags
Mitglied auf SA_SIGINFO setzen, aber ich kann mich nicht erinnern, warum ich diesen Aberglauben habe. Ich glaube, dies wird Ihrem Prozess einen Signalhandler geben, der ohne Rennbedingungen eingestellt bleibt und der nicht von den meisten anderen Signalen unterbrochen wird.
Schreiben Sie Ihre Signalhandlerfunktion sehr, sehr sorgfältig. Stellen Sie einfach eine globale Variable ein, um anzuzeigen, dass ein Signal abgefangen wurde, und lassen Sie den Rest des Prozesses die gewünschte Aktion für dieses Signal ausführen. Auf diese Weise werden die Signale für die geringste Zeit maskiert.
Außerdem sollten Sie Ihren Signalverarbeitungscode sehr gründlich testen. Stellen Sie es in einen kleinen Testprozess und senden Sie so viele SIGUSR1- und SIGUSR2-Signale wie möglich, möglicherweise von 2 oder 3 speziellen Signal-Sendeprogrammen. Mischen Sie auch einige andere Signale ein, nachdem Sie sicher sind, dass Ihr Code SIGUSR1 und SIGUSR2 schnell und korrekt verarbeiten kann. Bereiten Sie sich auf schwieriges Debuggen vor.
Wenn Sie Linux und nur Linux verwenden, können Sie signalfd()
einen Dateideskriptor erstellen, den Sie abrufen select()
oder abfragen können, um diese Signale zu empfangen. Die Verwendung signalfd()
erleichtert möglicherweise das Debuggen.
signal(2)
darauf hingewiesen, dass Sie diese Verwirrung vermeiden, indem Siesigaction(2)
stattdessen verwenden.