web-dev-qa-db-fra.com

Quelle est la différence entre join () et detach () pour le multi-threading en C ++?

Quelle est la différence entre join() et detach() dans le multi-threading en C++? join() tue-t-il le thread?

17
r.hg

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):

  • Un objet thread construit par défaut ne représente pas un thread d'exécution, il n'est donc pas joignable.
  • Un thread qui a été déplacé ne représentera plus un thread d'exécution, il n'est donc pas joignable.
30
Michael Burr

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();
}
11
dim-an