Je viens de lire la documentation sur std :: thread.detach ()
en C ++ 11.
Voici mon test:
#include <iostream> #include <thread> #include <chrono> static int counter = 0; void func() { while (true) { std::cout<<"running..."<<std::endl; std::cout<<counter++<<std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(1000)); } } int main() { { std::thread t(func); t.detach(); } // t is released after this line // t has died, so who is holding the resources of the detached thread??? std::cin.get(); return 0; }
Ce code fonctionne comme prévu. Il semble donc que le thread puisse continuer à fonctionner même si son destructeur a été appelé. Est-ce vrai?
Si c'est vrai, qui sur terre détient les ressources du thread après la libération de l'objet t? Existe-t-il un mécanisme pour conserver les ressources, par exemple, un objet anonyme caché?
3 Réponses :
Les threads d'exécutions existent indépendamment des objets thread que vous utilisez pour les gérer en C ++. Lorsque vous détachez un objet thread, le thread d'exécution continue de s'exécuter, mais l'implémentation (généralement en combinaison avec le système d'exploitation) en est responsable.
Vous avez raison de dire que le thread continue de fonctionner s'il est détaché après le destructeur du thread.
Personne sur terre ne détient les ressources (sauf si vous prenez des dispositions pour que quelqu'un le fasse). Cependant, lorsque votre application se termine, le processus d'arrêt de l'application mettra fin au thread.
On peut encore s'arranger pour communiquer avec et "attendre" un thread détaché. En substance, join ()
est une API pratique pour que vous n'ayez pas à faire quelque chose comme ceci:
#include <atomic> #include <chrono> #include <iostream> #include <thread> static int counter = 0; std::atomic<bool> time_to_quit{false}; std::atomic<bool> has_quit{false}; void func() { while (!time_to_quit) { std::cout<<"running..."<<std::endl; std::cout<<counter++<<std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(1000)); } has_quit = true; } int main() { { std::thread t(func); t.detach(); } // t is released after this line using namespace std::chrono_literals; std::this_thread::sleep_for(3s); time_to_quit = true; while (!has_quit) ; std::cout << "orderly shutdown\n"; }
En C ++, std :: thread
ne gère pas le thread d'exécution lui-même. C ++ n'a pas du tout de contrôle pour gérer le thread d'exécution.
std :: thread
gère le handle de thread - l'identifiant d'un thread ( thread_t
dans le monde Posix, qui était en grande partie un modèle pour std :: thread
). Un tel identifiant est utilisé pour communiquer (comme en control ) avec le thread, mais en C ++, le seul moyen de communication standard serait de rejoindre
le thread (qui attend simplement pour l'achèvement du thread) ou détachez-vous
de celui-ci.
Lorsque le destructeur de std :: thread
est appelé, le handle de thread est également détruit et aucun contrôle supplémentaire du thread n'est possible. Mais le fil d'exécution lui-même reste et continue d'être géré par l'implémentation (ou, plus précisément, le système d'exploitation).
Veuillez noter que pour les threads non détachés, les destructeurs de std :: thread
lèvent une exception si le thread n'a pas été joint. Il s'agit simplement d'une protection contre les développeurs qui perdent accidentellement la poignée de thread alors qu'ils n'avaient pas l'intention de le faire.