Die C++ Einfädeln Einrichtungen tun nicht umfassen einen eingebauten Mechanismus zum Abschließen eines Thread aufgerufen wurde. Stattdessen müssen Sie selbst entscheiden: a) einen Mechanismus, um dem Thread zu signalisieren, dass er beendet werden sollte, b) dass es Ihnen egal ist, dass der Thread mitten in der Operation abgebrochen wird, wenn der Prozess beendet wird und das Betriebssystem seine Threads einfach nicht mehr ausführt Mehr.
Das Objekt std::thread
ist nicht der Thread selbst, sondern ein undurchsichtiges Objekt, das einen Deskriptor/Handle für den Thread enthält, also theoretisch zerstört werden könnte, ohne den Thread zu beeinflussen, und es gab Argumente für und gegen die automatische Beendigung des Threads . Stattdessen wurde als ein Kompromiss gemacht, dass das Zerstören eines std::thread
Objekts, während der Thread ausgeführt und angehängt wurde, zum Beenden der Anwendung führen würde.
Als Ergebnis Darin Destruktor gibt es einige Code wie folgt:
~thread() {
if (this->joinable())
std::terminate(...);
}
Hier ist ein Beispiel für eine einfache atomare Variable und im Thread für sie zu prüfen. Für komplexere Fälle müssen Sie möglicherweise einen condition_variable
oder einen anderen komplexeren Signalmechanismus in Betracht ziehen.
#include <thread>
#include <atomic>
#include <chrono>
#include <iostream>
class S {
std::atomic<bool> running_;
std::thread thread_;
public:
S() : running_(true), thread_([this]() { work(); }) {}
void cancel() { running_ = false; }
~S() {
if (running_)
cancel();
if (thread_.joinable())
thread_.join();
}
private:
void work() {
while (running_) {
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << "tick ...\n";
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << "... tock\n";
}
std::cout << "!running\n";
}
};
int main()
{
std::cout << "main()\n";
{
S s;
std::this_thread::sleep_for(std::chrono::milliseconds(2750));
std::cout << "end of main, should see a tock and then end\n";
}
std::cout << "finished\n";
}
Live-Demo: http://coliru.stacked-crooked.com/a/3b179f0f9f8bc2e1
Siehe http://stackoverflow.com/a/13984169/12711 –
@kfsone danke für den Kommentar. Könnten Sie etwas mehr angeben, auf das undefiniertes Verhalten Thread (& Bar :: foo, das) auf – user695652
@ user695652 angewiesen ist, ist es generell gefährlich, 'this' (oder Objektmitglieder) in der Initialisierungsliste eines Konstruktors zu übergeben. Ihr Objekt enthält nur den Thread, so dass es in diesem Beispiel keinen Schaden gibt, aber wenn es mehr Felder hat, sollten Sie darauf achten, dass Ihr Thread ausgeführt werden könnte, bevor Ihr Objekt vollständig aufgebaut ist. – zneak