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
}
Dans le destructeur de std::thread
, std::terminate
Est appelé si:
t.join()
)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
?
join
detach
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é.
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.
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.