Quelle est la différence entre join()
et detach()
dans le multi-threading en C++? join()
tue-t-il le thread?
Un objet C++ thread
représente généralement (mais pas toujours) un thread d'exécution, qui est un concept de système d'exploitation ou de plate-forme.
Lorsque thread::join()
est appelée, le thread appelant se bloque jusqu'à ce que le thread d'exécution soit terminé. Fondamentalement, c'est un mécanisme qui peut être utilisé pour savoir quand un thread est terminé. Lorsque thread::join()
revient, le thread d'exécution du système d'exploitation est terminé et l'objet C++ thread
peut être détruit.
La thread::detach()
est appelée, le thread d'exécution est "détaché" de l'objet thread
et n'est plus représenté par un objet thread
- ce sont deux choses indépendantes. L'objet C++ thread
peut être détruit et le thread d'exécution du système d'exploitation peut continuer. Si le programme doit savoir quand ce thread d'exécution est terminé, un autre mécanisme doit être utilisé. join()
ne peut plus être appelé sur cet objet thread
, car il n'est plus associé à un thread d'exécution.
Il est considéré comme une erreur de détruire un objet C++ thread
alors qu'il est toujours "joignable". C'est-à-dire que pour détruire un objet C++ thread
, join()
doit être appelé (et terminé) ou detach()
doit être appelé. Si un objet C++ thread
est toujours joignable lorsqu'il est détruit, une exception sera levée.
Quelques autres façons qu'un objet C++ thread
ne représentera pas un thread d'exécution (c'est-à-dire, peut être non joignable):
thread
construit par défaut ne représente pas un thread d'exécution, il n'est donc pas joignable.join()
ne tue pas le thread. En fait, il attend le retour de la fonction principale du thread. Donc, si votre fonction principale de thread ressemble à ceci:
while (true) {
}
join()
va attendre indéfiniment.
detatch()
ne tue pas non plus le thread. En fait, il indique à std::thread
Que ce thread doit continuer à s'exécuter même lorsque l'objet std::thread
Est détruit. C++ vérifie dans std :: thread destructor que le thread est joint ou détaché et termine le programme si cette vérification échoue.
Donc, si vous décommentez la première ligne de la fonction main
du code suivant, elle se bloquera. Si vous décommentez la deuxième ou la troisième ligne, cela fonctionnera bien.
#include <thread>
void func() {
}
void fail1() {
std::thread t(func);
// will fail when we try to destroy t since it is not joined or detached
}
void works1() {
std::thread t(func);
t.join();
}
void works2() {
std::thread t(func);
t.detach();
}
int main() {
// fail1();
// works1();
// works2();
}