Quand dois-je utiliser std::thread::détacher?

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 fonctionnera en utilisant un thread indépendamment.

Ne pas se détacher:

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

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

    //some code here
}

Appel avec détachement:

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

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

    t.detach();

    //some code here
}
89
demandé sur Jeffmagma 2014-04-02 10:51:43

4 réponses

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

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

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


Lorsqu'un programme se termine (c'est-à-dire que main retourne), les threads détachés restants s'exécutant en arrière-plan ne sont pas attendus; à la place, leur exécution est suspendue et leur fil-objets locaux détruits.

Fondamentalement, 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, cela pourrait être une situation aussi grave que si le programme s'était écrasé ou avait été tué. Espérons que le système d'exploitation va libérer les verrous sur les fichiers, etc... mais vous pourriez avoir corrompu la mémoire partagée, les fichiers à moitié écrits, etc.


Donc, devriez-vous utiliser join ou detach ?

  • Utiliser join
  • sauf si vous avez besoin de plus de flexibilité et êtes prêt à fournir un mécanisme de synchronisation pour attendre l'achèvement du thread par vous-même , auquel cas vous pouvez utiliser detach
96
répondu Matthieu M. 2014-04-02 07:50:04

Vous devriez appeler detach si vous n'attendez pas que le thread se termine avec join mais le thread continuera à fonctionner jusqu'à ce qu'il soit terminé, puis se terminera sans que le thread principal l'attende spécifiquement.

detach fondamentalement, permettra de libérer les ressources nécessaires pour être en mesure de mettre en œuvre join.

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

19
répondu 6502 2018-09-25 19:33:55

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

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

detach() est principalement utile lorsque vous avez une tâche qui doit être faite 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 silencieusement un thread de travail en arrière-plan et le détacher pour que vous ne le remarquiez même pas.

7
répondu GreenScape 2017-11-01 15:00:40

Selon cppreference.com:

Sépare le thread d'exécution de l'objet thread, permettant exécution pour continuer indépendamment. Toutes les ressources allouées seront libéré une fois le thread sorti.

Après avoir appelé detach *this ne possède plus de thread.

Par exemple:

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

Notez que la variable locale: my_thread, tandis que la durée de 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 devriez plus utiliser my_thread, mais si la durée de vie de my_thread est terminée, rien n'arrivera au nouveau thread.

0
répondu DinoStray 2018-07-17 09:50:54