Ich muss den Thread nicht korrekt beenden oder auf einen "Beenden" -Befehl reagieren lassen. Ich bin daran interessiert, den Thread mit reinem C ++ 11 gewaltsam zu beenden.
c++
multithreading
c++11
Alexander V.
quelle
quelle
Antworten:
Sie können
std::terminate()
von jedem Thread aus aufrufen, und der Thread, auf den Sie sich beziehen, wird zwangsweise beendet.Sie können veranlassen
~thread()
, dass die Ausführung für das Objekt des Zielthreads ausgeführt wird, ohne dass eine Interventionjoin()
oderdetach()
für dieses Objekt erfolgt. Dies hat den gleichen Effekt wie Option 1.Sie können eine Ausnahme entwerfen, die einen Destruktor hat, der eine Ausnahme auslöst. Und veranlassen Sie dann, dass der Ziel-Thread diese Ausnahme auslöst, wenn sie zwangsweise beendet werden soll. Der schwierige Teil in diesem Fall besteht darin, dass der Ziel-Thread diese Ausnahme auslöst.
Die Optionen 1 und 2 verlieren keine prozessinternen Ressourcen, beenden jedoch jeden Thread.
Option 3 wird wahrscheinlich Ressourcen verlieren, ist jedoch teilweise kooperativ, da der Ziel-Thread zustimmen muss, um die Ausnahme auszulösen.
In C ++ 11 gibt es keine tragbare Möglichkeit (wie mir bekannt ist), einen einzelnen Thread in einem Multithread-Programm nicht kooperativ zu beenden (dh ohne alle Threads zu beenden). Es gab keine Motivation, ein solches Feature zu entwerfen.
A
std::thread
kann diese Mitgliedsfunktion haben:Möglicherweise können Sie damit eine betriebssystemabhängige Funktion aufrufen, um das zu tun, was Sie möchten. Zum Beispiel unter Apples Betriebssystemen existiert diese Funktion und
native_handle_type
ist einepthread_t
. Wenn Sie erfolgreich sind, werden Sie wahrscheinlich Ressourcen verlieren.quelle
std::terminate
Weder werden statische Destruktoren aufgerufen, noch werden Ausgabepuffer geleert, sodass die Reihenfolge, in der Ressourcen freigegeben werden, nicht genau definiert ist. Sie können auch nicht garantieren, dass Ihre Daten für den Benutzer sichtbar sind oder in einen permanenten Speicher geschrieben werden oder sogar konsistent und vollständig.exit()
oderabort()
den gleichen Gesamteffekt erzielen.@ Howard Hinnants Antwort ist sowohl richtig als auch umfassend. Aber es könnte missverstanden werden, wenn es zu schnell gelesen wird, weil
std::terminate()
(der gesamte Prozess) zufällig den gleichen Namen hat wie das "Beenden", das @AlexanderVX im Sinn hatte (1 Thread).Zusammenfassung: "1 Thread beenden + gewaltsam (Ziel-Thread kooperiert nicht) + reines C ++ 11 = Auf keinen Fall."
quelle
std::terminate()
Antwort ist wie eine klassische schelmische Dschinn-Geschichte. es erfüllt alles im Wunsch des OP auf den Brief, wenn auch wahrscheinlich nicht so, wie er es meinte . Der zurückhaltende Humor brachte mich zum Lächeln. :-)Diese Frage hat tatsächlich einen tieferen Charakter und ein gutes Verständnis der Multithreading-Konzepte im Allgemeinen gibt Ihnen Einblick in dieses Thema. Tatsächlich gibt es keine Sprache oder kein Betriebssystem, das Ihnen die Möglichkeit bietet, einen asynchronen abrupten Thread-Abbruch ohne Warnung durchzuführen, diese nicht zu verwenden. Alle diese Ausführungsumgebungen empfehlen Entwicklern dringend oder erfordern sogar das Erstellen von Multithreading-Anwendungen auf der Basis einer kooperativen oder synchronen Thread-Beendigung. Der Grund für diese gemeinsamen Entscheidungen und Ratschläge ist, dass sie alle auf demselben allgemeinen Multithreading-Modell basieren.
Vergleichen wir Multiprozessor- und Multithreading-Konzepte, um die Vor- und Nachteile des zweiten besser zu verstehen.
Bei der Mehrfachverarbeitung wird die Aufteilung der gesamten Ausführungsumgebung in eine Reihe vollständig isolierter Prozesse vorausgesetzt, die vom Betriebssystem gesteuert werden. Der Prozess enthält und isoliert den Status der Ausführungsumgebung, einschließlich des lokalen Speichers des Prozesses und der darin enthaltenen Daten sowie aller Systemressourcen wie Dateien, Sockets und Synchronisationsobjekte. Isolation ist ein kritisch wichtiges Merkmal des Prozesses, da sie die Fehlerausbreitung durch die Prozessgrenzen begrenzt. Mit anderen Worten, kein Prozess kann die Konsistenz eines anderen Prozesses im System beeinflussen. Gleiches gilt für das Prozessverhalten, jedoch weniger eingeschränkt und unscharfer. In einer solchen Umgebung kann jeder Prozess in jedem "beliebigen" Moment beendet werden, da erstens jeder Prozess isoliert ist, zweitens
Im Gegensatz dazu setzt Multithreading voraus, dass mehrere Threads im selben Prozess ausgeführt werden. Alle diese Threads haben jedoch dieselbe Isolationsbox und es gibt keine Betriebssystemsteuerung für den internen Status des Prozesses. Infolgedessen kann jeder Thread den globalen Prozessstatus ändern und ihn beschädigen. Gleichzeitig hängen die Punkte, an denen der Status des Threads bekanntermaßen sicher ist, um einen Thread vollständig zu beenden, von der Anwendungslogik ab und sind weder für das Betriebssystem noch für die Laufzeit der Programmiersprache bekannt. Infolgedessen bedeutet das Beenden eines Threads zum beliebigen Zeitpunkt das Beenden des Threads an einem beliebigen Punkt seines Ausführungspfads und kann leicht zu prozessweiter Beschädigung der Daten, Speicher und Leckagen führen.
Aus diesem Grund besteht der übliche Ansatz darin, Entwickler zu zwingen, eine synchrone oder kooperative Thread-Beendigung zu implementieren, wobei der eine Thread eine andere Thread-Beendigung anfordern kann und ein anderer Thread an einem genau definierten Punkt diese Anforderung überprüfen und das Herunterfahren aus dem genau definierten Zustand starten kann mit der Freigabe aller globalen systemweiten Ressourcen und lokalen prozessweiten Ressourcen auf sichere und konsistente Weise.
quelle
Tipps zur Verwendung der betriebssystemabhängigen Funktion zum Beenden des C ++ - Threads:
std::thread::native_handle()
Nur der gültige native Handle-Typ des Threads kann vor dem Aufruf vonjoin()
oder abgerufen werdendetach()
. Danach wirdnative_handle()
0 zurückgegeben -pthread_cancel()
wird coredump.Um die native Thread-Beendigungsfunktion (z. B.
pthread_cancel()
) effektiv aufzurufen , müssen Sie das native Handle speichern, bevor Siestd::thread::join()
oder aufrufenstd::thread::detach()
. Damit Ihr nativer Terminator immer ein gültiges natives Handle verwendet.Weitere Erklärungen finden Sie unter: http://bo-yang.github.io/2017/11/19/cpp-kill-detached-thread .
quelle
Ich denke, der Thread, der getötet werden muss, befindet sich entweder in einem Wartemodus oder erledigt schwere Arbeit. Ich würde vorschlagen, einen "naiven" Weg zu verwenden.
Definieren Sie einen globalen Booleschen Wert:
Fügen Sie den folgenden Code (oder einen ähnlichen Code) in mehrere wichtige Punkte ein, sodass alle Funktionen im Aufrufstapel zurückgegeben werden, bis der Thread natürlich endet:
So stoppen Sie den Thread von einem anderen (Haupt-) Thread:
quelle