web-dev-qa-db-fra.com

Quand devrais-je utiliser std :: thread :: detach?

Parfois, je dois utiliser std::thread Pour accélérer mon application. Je sais aussi que join() attend qu'un thread se termine. C'est facile à comprendre, mais quelle est la différence entre appeler detach() et ne pas l'appeler?

Je pensais que sans detach(), la méthode du thread fonctionnerait en utilisant un thread indépendamment.

Ne pas détacher:

void Someclass::Somefunction() {
    //...

    std::thread t([ ] {
        printf("thread called without detach");
    });

    //some code here
}

Appeler avec détacher:

void Someclass::Somefunction() {
    //...

    std::thread t([ ] {
        printf("thread called with detach");
    });

    t.detach();

    //some code here
}
115
Jinbom Heo

Dans le destructeur de std::thread, std::terminate Est appelé si:

  • le thread n'a pas été rejoint (avec t.join())
  • et n'a pas été détaché non plus (avec t.detach())

Ainsi, vous devriez toujours soit join ou detach un thread avant que les flux d'exécution n'atteignent le destructeur.


Quand un programme se termine (c'est-à-dire que main retourne), les threads détachés restant exécutés en arrière-plan ne sont pas attendus; à la place, leur exécution est suspendue et leurs objets thread-local sont détruits.

De manière cruciale, cela signifie que la pile de ces threads n’est pas déroulée et que certains destructeurs ne sont donc pas exécutés. Selon les actions que ces destructeurs étaient censés entreprendre, la situation pourrait être aussi grave que si le programme s'était écrasé ou avait été tué. Espérons que le système d'exploitation libérera les verrous sur les fichiers, etc., mais vous pourriez avoir corrompu la mémoire partagée, les fichiers à moitié écrits, etc.


Alors, devriez-vous utiliser join ou detach?

  • Utilisez join
  • Sauf si vous avez besoin de plus de flexibilité ET êtes prêt à fournir un mécanisme de synchronisation pour attendre la fin du thread vous-même, auquel cas vous pouvez utiliser detach
121
Matthieu M.

Vous devez appeler detach si vous n'attendez pas que le fil soit terminé avec join mais le fil continuera à fonctionner jusqu'à ce que l'opération soit terminée et se terminera sans que le thread principal attende c'est spécifiquement.

detach libérera les ressources nécessaires pour pouvoir implémenter join.

C'est une erreur fatale si un objet thread termine sa vie et que ni join ni detach n'ont été appelés; dans ce cas, terminate est appelé.

21
6502

Lorsque vous détachez un thread, cela signifie que vous n'avez pas besoin de join() avant de quitter main().

La bibliothèque de threads attendra réellement chacun de ces threads nder-main, mais vous ne devriez pas vous en soucier.

detach() est principalement utile lorsque vous avez une tâche à exécuter en arrière-plan, mais que vous ne vous souciez pas de son exécution. C'est généralement le cas pour certaines bibliothèques. Ils peuvent créer en silence un thread de travail en arrière-plan et le détacher pour que vous ne le remarquiez même pas.

9
GreenScape

Selon cppreference.com :

Sépare le thread d'exécution de l'objet thread, permettant ainsi à l'exécution de continuer de manière indépendante. Toutes les ressources allouées seront libérées une fois le thread terminé.

Après avoir appelé detach, *this Ne possède plus aucun fil.

Par exemple:

  std::thread my_thread([&](){XXXX});
  my_thread.detach();

Notez la variable locale: my_thread, Alors que la vie de my_thread Est terminée, le destructeur de std::thread Sera appelé et std::terminate() sera appelé dans le destructeur.

Mais si vous utilisez detach(), vous ne devez plus utiliser my_thread, Même si la durée de vie de my_thread Est terminée, le nouveau fil ne risque pas de se perdre.

1
DinoStray