Ich habe eine Klasse mit einem benutzerdefinierten Destruktor. Wenn die Klasse anfänglich instanziiert wurde und dann SIGINT ausgegeben wird (unter Verwendung von STRG + C in Unix), während das Programm läuft, wird der Destruktor aufgerufen? Was ist das Verhalten für SIGSTP (STRG + Z in Unix)?Wird Destructor aufgerufen, wenn SIGINT oder SIGSTP ausgegeben wird?
Antwort
Nein, standardmäßig verursachen die meisten Signale einen sofortigen, anormalen Ausgang Ihres Programms.
Sie können jedoch das Standardverhalten für die meisten Signale leicht ändern.
Dieser Code zeigt, wie ein Signal Ausgang Ihr Programm normal zu machen, einschließlich der Aufforderung alle üblichen Destruktoren:
#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <cstring>
#include <atomic>
std::atomic<bool> quit(false); // signal flag
void got_signal(int)
{
quit.store(true);
}
class Foo
{
public:
~Foo() { std::cout << "destructor\n"; }
};
int main(void)
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = got_signal;
sigfillset(&sa.sa_mask);
sigaction(SIGINT,&sa,NULL);
Foo foo; // needs destruction before exit
while (true)
{
// do real work here...
sleep(1);
if(quit.load()) break; // exit normally after SIGINT
}
return 0;
}
Wenn Sie das Programm und drücken Steuer-C ausführen, sollten Sie das Wort „destructor“ sehen gedruckt. Seien Sie sich bewusst, dass Ihre Signal-Handler-Funktionen (got_signal) selten funktionieren sollten, außer dass Sie eine Markierung setzen und ruhig zurückkehren, es sei denn, Sie wissen wirklich, was Sie tun.
Die meisten Signale sind abfangbare, wie oben gezeigt, aber nicht SIGKILL, Sie haben keine Kontrolle über sie, weil SIGKILL ein letzter verzweifelter Methode ist es, einen außer Kontrolle geratenen Prozess für das Töten und SIGSTOP nicht, welche einem Benutzer ermöglicht, einen Prozess kalt einzufrieren. Beachten Sie, dass Sie bei Bedarf SIGTSTP (control-Z) abfangen können. Dies ist jedoch nicht erforderlich, wenn Ihr einziges Interesse an Signalen das Destruktorverhalten ist, da der Prozess schließlich nach einem control-Z aktiviert wird, weiterläuft und wird normal mit allen aktiven Destruktoren beendet.
Wenn Sie diese Signale nicht selbst behandeln, dann werden die Destruktoren nicht aufgerufen. Das Betriebssystem wird jedoch alle Ressourcen zurückfordern, die von Ihrem Programm beim Beenden verwendet wurden.
Wenn Sie Signale selbst verarbeiten möchten, sollten Sie die Standardbibliotheksfunktion sigaction
ausprobieren.
Zurückfordern von Ressourcen, die dem Betriebssystem gehören. Innerhalb einer Anwendung gibt es noch andere Ressourcen, die normalerweise so eingepackt sind, dass sie korrekt geschlossen werden müssen (andernfalls erhalten Sie beschädigte Ressourcen (wie eine Datei, die nicht ordnungsgemäß beendet wird)). –
Lassen Sie uns es versuchen:
#include <stdio.h>
#include <unistd.h>
class Foo {
public:
Foo() {};
~Foo() { printf("Yay!\n"); }
} bar;
int main(int argc, char **argv) {
sleep(5);
}
Und dann:
$ g++ -o test ./test.cc
$ ./test
^C
$ ./test
Yay!
So habe ich Angst nicht, Sie werden es fangen.
Wie für SIGSTOP
, kann es nicht gefangen werden, und pausiert den Prozess, bis eine SIGCONT
gesendet wird.
- 1. pthread_key_create destructor wird nicht aufgerufen
- 2. Destructor aufrufen, wenn Programm unterbrochen wird
- 3. Wenn ein Datum in einer CouchDB Map-Funktion ausgegeben wird - was wird für das Datumsobjekt aufgerufen?
- 4. Welche Exception wird ausgegeben, wenn der Thread unerwartet beendet wird?
- 5. WARNUNG wird ausgegeben, wenn eingebetteter Tomcat-Server
- 6. Was wird ausgedruckt, wenn dolookup aufgerufen wird?
- 7. Response.Cookies wird zurückgesetzt, wenn RedirectToAction aufgerufen wird
- 8. Wie wird Unicode ausgegeben?
- 9. Wird save() implizit aufgerufen, wenn create in django aufgerufen wird?
- 10. Datum wird falsch ausgegeben
- 11. Destructor aufgerufen, wenn Objekte von Wert übergeben werden
- 12. Wenn Dialog in Aktivität angezeigt wird oder abgewiesen wird, wird die Methode Aktivitätslebenszyklus aufgerufen
- 13. Benutzerdefinierter Springfilter wird nicht aufgerufen, wenn auf die Webanwendung zugegriffen wird oder die URL gefunden wird
- 14. C#/CLI: Destructor nicht aufgerufen, wenn Dispose(), die in es
- 15. Wenn Konstruktor aufgerufen wird und wenn Operatorfunktion
- 16. Warum wird SIGINT hier nicht erwischt?
- 17. Server-Push, wenn eine Funktion aufgerufen wird: Ajax oder WebSockets
- 18. Warum wird das Programm ausgegeben?
- 19. Destructor nicht aufgerufen, wenn eine lokale Instanz der Rückkehr
- 20. onOptionsItemSelected wird nicht aufgerufen, wenn actionLayout (SherlockActionBar) verwendet wird
- 21. textFieldShouldBeginEditing wird mehrfach aufgerufen, wenn die "Tab" -Taste gedrückt wird
- 22. Wird finally() aufgerufen, wenn die Stopptaste in Eclipse gedrückt wird?
- 23. PHP-Konstruktor wird nicht aufgerufen? oder so?
- 24. Wenn AppInitialize-Methode in ASP.NET aufgerufen wird?
- 25. Wird exit() oder eine Ausnahme verhindern, dass ein End-of-Scope-Destruktor aufgerufen wird?
- 26. UNUserNotificationCenter didRecieve Antwort wird nicht aufgerufen, wenn App beendet wird
- 27. AJAX-Anforderung wird nicht aufgerufen oder ausgeführt
- 28. PerformFetchWithCompletionHandler wird zweimal aufgerufen, wenn mit Xcode
- 29. Shared Library wird in stdout ausgegeben
- 30. Ausführungsstopps, wenn die Methode aufgerufen wird
IIRC, der korrekte Typ von 'quit' sollte' volatile std :: sig_atomic_t' sein. Es ist UB, 'bool' zu diesem Zweck zu verwenden. – MSalters
@MSalters: Richtig, ich hätte einen sigfillset() Aufruf vor sigaction() eingefügt, was wahrscheinlich sogar besser als sig_atomic_t wäre. Die Verwendung eines Bool ist vertrauter und vollkommen sicher, wenn zusätzliche Signale daran gehindert werden, den Signal-Handler zu unterbrechen. Bearbeitet meinen Beispielcode, danke. –
Ich bekomme tatsächlich einen Fehler mit diesem Code: 'Verwendung der gelöschten Funktion' für die' quit = false' Zeile. Du musst 'quit (false)' anstelle von 'quit = false' machen. Beachten Sie auch, dass dieser Code unter Windows nicht funktioniert. Sie müssen 'SetConsoleCtrlHandler()' verwenden. – Timmmm