2016-09-08 1 views
2

La bibliothèque standard fournit une classe mutex, avec la possibilité de verrouiller manuellement et déverrouiller:équivalent thread_guard Pour lock_guard/unique_lock

std::mutex m; 
m.lock(); 
// ... 
m.unlock(); 

Cependant, la bibliothèque reconnaît aussi apparemment qu'une affaire commune est juste pour verrouiller le mutex à un certain point, et le déverrouiller en quittant un bloc. Pour cela, il fournit std::lock_guard et std::unique_lock:

std::mutex m; 
std::lock_guard<std::mutex> lock(m); 
// ... 

// Automatic unlock 

Je pense qu'un motif assez courant pour les fils, est de créer une (que ce soit en tant que variable de la pile, ou un membre), puis join it before destructing it:

std::thread t(foo); 
// ... 
t.join(); 

il semble facile d'écrire un thread_guard, qui prendrait une thread (ou une séquence de thread s), et serait tout simplement appeler join sur sa propre destruction:

std::thread t(foo); 
thread_guard<std::thread> g(t); 
// ... 
// Join automatically 
  1. Existe-t-il une classe de bibliothèque standard comme celle-ci?

  2. Si non, y a-t-il une raison pour éviter cela?

+0

Vous pouvez toujours détacher le fil, et il serait "joint" (pas vraiment joint, mais le même nettoyage des ressources se produirait) automatiquement lorsque le fil se termine. –

+0

@JoachimPileborg Merci. Détacher fait quelque chose de différent, cependant, non? Si vous vous joignez (directement, indirectement) avant de quitter un bloc, vous savez que, une fois le bloc terminé, le thread a fini. –

+0

'joining_thread' a été récemment proposé mais [abattu] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0379r0.html). –

Répondre

4

Cette question est abordée dans le livre de Scott Meyer « Modern efficace C++ »

Le problème est que s'il y aurait un autre comportement par défaut (détachez ou joindre) causerait difficile de trouver des erreurs dans le cas où vous oubliez qu'il y a une opération implicite. Ainsi, le comportement par défaut réel sur la destruction est affirmer s'il n'est pas explicitement joint ou détaché. Et aucune classe "Garde" n'est là aussi pour cette raison.

Si vous toujours souhaitez vous joindre il est sûr d'écrire une telle classe vous-même. Mais quand quelqu'un l'utilise et veut se détacher, les gens peuvent oublier que le destructeur le rejoindra implicitement. Donc, c'est le risque d'écrire une telle fonction. Comme alternative, vous pouvez utiliser un scope_guard par boost ou la folie de la bibliothèque (que personnellement je préfère plus) et déclarer au début explicitement votre intention et il sera exécuté. Ou vous pouvez écrire une classe "Guard" basée sur une politique dans laquelle vous devez explicitement indiquer ce que vous voulez faire lors de la destruction.

+1

Merci. Ne peut pas lire Scott Meyers trop de fois! –