Est-ce que le comportement indéfini des fuites std :: thread?

Raison pour laquelle quelqu’un serait intéressé par

//... new std::thread (func,arg1,arg2); } 

Est-ce que std::thread destructor (contrairement à boost::thread ) tue le thread. func termine c’est du temps. Ma question est la suivante dans les cas suivants:

Cas 1: disons que cette fonction prend arg1, arg2 par valeur.
Cas 2: disons que la fonction prend arg1, arg2 par référence – cela sonne mal si vous me le demandez, car je suppose qu’à la fin de l’étendue où thread est créé, arg1 et arg2 seront effacés par leurs destructeurs.

BTW est std :: thread destructor (c’est ce qu’on appelle AFAIK lorsque func termine) suffisamment intelligent pour effacer toutes les ressources utilisées par thread? Je veux dire que si je crée des threads 1M (souvent pas en même temps) avec de nouveaux et qu’ils finissent tous, est-ce que j’ai des fuites permanentes?

Un object std :: thread représente un thread, ce n’est pas un “vrai” thread, c’est un concept géré par le système d’exploitation.

Par conséquent, ici vous perdez un object std :: thread parce que vous ne le supprimez pas. Le destructeur n’est jamais appelé. Mais le fil qu’il représentait finira quand ses instructions se termineront, comme n’importe quel fil.

Si le destructeur a été appelé avant la fin des instructions, par exemple si vous aviez créé cet object sur la stack et qu’il y avait beaucoup de choses à faire dans ce nouveau thread, l’appel du destructeur aurait alors déclenché std :: terminate ( ). Vous devez appeler detach () pour permettre au thread de continuer après la destruction de l’occurrence de std :: thread.

De cette façon, vous devez indiquer explicitement si vous voulez ou non que ce fil se termine lorsque l’instance de std :: thread est détruite: si vous voulez qu’il continue, appelez detach (); si vous voulez attendre la fin, appelez join ().

Donc, dans votre cas, vous perdez de la mémoire mais le thread doit continuer car l’object std :: thread vit “pour toujours” car vous avez perdu tout moyen de le contrôler.

BTW est std :: thread destructor (c’est ce qu’on appelle AFAIK lorsque func termine) suffisamment intelligent pour effacer toutes les ressources utilisées par thread? Je veux dire que si je crée des threads 1M (souvent pas en même temps) avec de nouveaux et qu’ils finissent tous, est-ce que j’ai des fuites permanentes?

Normalement, le destructeur est appelé automatiquement lorsqu’un object de la stack sort de sa scope (ou lors du déroulement de la stack lorsqu’une exception est interceptée). Etant donné que l’object thread est alloué sur le tas à l’aide de new le destructeur ne sera pas appelé automatiquement, un code doit donc delete l’object pour appeler son destructeur. En d’autres termes, le destructeur de thread n’est pas appelé à la fin de func() .

Ce n’est pas OK selon le texte final. Plus précisément, le destructeur d’un thread qui n’a été ni join ni detach appellera std::terminate .

std::thread destructor n’est pas appelé lorsque le rappel est renvoyé, mais lorsque l’object thread est hors de scope, comme tout autre object. Ainsi, un new thread ‘d qui ne sera jamais delete ‘ d ne sera jamais détruit, laissant filtrer tout état associé (et des choses potentiellement terriblement mauvaises si / lorsque le programme se termine avec des threads supplémentaires toujours en cours d’exécution …)

Pour répondre à votre question sur les durées de vie, std::thread est semblable à std::bind : il stocke des copies de ses arguments et les transmet au rappel, que le rappel prenne ses arguments par valeur ou par référence. Vous devez explicitement encapsuler les arguments avec std::ref pour obtenir la sémantique de référence. Dans ce cas, comme d’habitude, vous devez vous assurer qu’aucune référence en suspens ne se produit (par exemple, en appelant thread::join() avant que toute variable référencée ne disparaisse de sa scope.)