signal-handler-Funktion in multithreaded-Umgebung
In meinem Multithread-GUI-Anwendung habe ich die folgenden signal-handling-code. Ich möchte, um dies zu verbessern-code so, dass es richtig ist und Gewindeschneiden sicher, aber es gibt einige Dinge, die ich nicht vollständig verstehen, in der signal-handling:
- ist das signal verarbeitet auf den Prozess oder thread-Ebene (kann ich die thread-spezifische signal-Handler) ?
- in dem thread-Kontext ist signal_handler Funktion ausgeführt ?
- ist es möglich, SIGTERM senden viele Signale in kurzer Zeit ?
- macht es Sinn, einen mutex verwenden, um zu verhindern, dass die parallele Ausführung von signal_handler ?
void signal_handler(int sig)
{
switch (sig)
{
case SIGTERM:
::wxLogMessage(wxT("SIGTERM signal received ..."));
break;
case SIGINT:
::wxLogMessage(wxT("SIGINT signal received ..."));
break;
case SIGUSR1:
::wxLogMessage(wxT("SIGUSR1 signal received ..."));
break;
default:
::wxLogMessage(wxT("Unknown signal received ..."));
}
//send wxCloseEvent to main application window
::wxGetApp().GetTopWindow()->Close(true);
}
Ich mich registrieren signal-Handler in meiner init-Funktion:
//register signal handlers
signal(SIGTERM, signal_handler);
signal(SIGINT, signal_handler);
signal(SIGUSR1, signal_handler);
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sehr vorsichtig sein: da die signal(7) Seite sagt, nur sehr wenige Funktionen (die "async-signal-safe" sind) werden können, (direkt oder indirekt) aufgerufen, in signal-Handlern. Mutex Verwandte Funktionen wahrscheinlich sollte nicht aufgerufen werden, im signal-Handler. Siehe auch pthreads(7)
Sollten Sie erwägen Einstellung ein flüchtige sigatomic_t variable im Signalhandler, und testen Sie den Wert der Flagge von Zeit zu Zeit.
Wenn Sie C++11 (oder C11) atomics, z.B. C++11 std::atomic oder C11
<stdatomic.h>
, Sie konnten machen, dassvolatile
variable auch atomic in diesem Sinne. Dann nutzen Sie die atomic-laden-Einrichtungen, um es zu testen.Die Qt-Dokumentation schlägt vor, die folgender trick: erstellen Sie eine Rohr(2) selbst beim Start, dann haben Sie Ihre signal-handler schreiben(2) (die
write
syscall ist angegeben als async-signal-safe) eine einzelne (oder mehrere) byte[N], um ein Rohr zu Ihres gleichen Prozess, und Ihre GUI-event-Schleife poll(2) das lese-Ende der pipe.Einen Linux-spezifische Möglichkeit zum verarbeiten von Signalen mit Qt sein könnte, um zu verwenden signalfd(2) wahrscheinlich mit QSocketNotifier (trotz des namens funktioniert es auf pollable Datei-Deskriptoren, nicht nur sockets). Mit anderen GUI-toolkits, kann man wohl auch hinzufügen, ein file-descriptor (eine vom
signalfd
oderpipe
) abgefragt werden.Einen einfachen Weg für den Umgang mit Signalen, die in einem multi-threaded-Anwendung zu erstellen, die einen thread wie einen dedizierten signal-Handhabungs-thread. Alle Signale, die von Interesse sind blockiert in jedem thread; kein signal-Handler eingerichtet sind; und die signal-handling-thread-Aufrufe
sigwaitinfo()
in einer Schleife, die auf die Signale, wie Sie sind, erhalten.Dies bedeutet, dass Sie brauchen nicht zu kümmern, ob die Funktionen, die Sie aufrufen möchten, sind async-signal-safe oder nicht, da die Signale nicht ausreichend im signal-Handler sind synchron behandelt von Ihrem dedizierten signal-Handhabungs-thread, die können, rufen Sie eine Funktion, die es mag (zum Beispiel, es kann die gewöhnliche Pthread-Synchronisierung Funktionen, um aufzuwachen einem anderen thread).
Diese Antwort bezieht sich auf POSIX-threads (
pthreads
).Bezogen 1:
Signale gehandhabt werden könnten, die auf thread-Ebene, ja. Wenn mehr als ein thread von einem Prozess verarbeitet ein signal, und das signal ist gesandt, um den Prozess, sondern auf einen bestimmten thread, es ist nicht festgelegt, welche thread-handler verarbeitet das signal. (siehe
man pthread_kill()
für details)Verweisen 2:
Den signal-handler wird excuted in den Kontext des Threads, der ihn gesetzt hat. Dies schließt den Haupt-thread.
Verweisen 3:
Wenn mehr als ein signal des gleichen Typs an den gleichen Prozess, den Sie möglicherweise verdichtet in in nur ein signal vor dem verlassen der signal-queue. Ob dies könnte zu differenzieren, um die thread-Ebene, weiß ich nicht sicher, muss ich zugeben.
Bezogen 4:
Wenn gemeinsame Ressourcen in das Spiel eingebunden: ja, zumindest für die Teile der Handler' code den Zugriff auf diese Ressourcen gleichzeitig. Und außerdem hängt dies auch auf die Logik, die Sie versuchen zu implementieren.