7
votes

S'appuyant sur ordre d'initialisation

Selon la norme C ++ 14, les variables de l'élément non statiques sont initialisées dans l'ordre dans lequel elles sont déclarées dans une classe. Le code de coupe ci-dessous repose sur cette règle pour contrôler une fonction de thread.

class foo
{
     foo(): 
          keep_going{true},
          my_thread(&foo::go,this)
     {}

      void go()
      {
          while(keep_going)
             check a std::condition_variable and do some work;
      }
      bool keep_going;
      std::thread my_thread;
}


3 commentaires

L'ordre d'initialisation n'est pas obscur, il est bien défini et il n'y a rien de mal à ce code.


1) Oui L'ordre d'initialisation fait partie des spécifications, 2) Oui - Documentation claire pourrait aider


Je me fierais seulement avec un bon commentaire expliquant. Suivez la citation 'Toujours le code comme votre code Maître est un tueur en série qui sait où vous vivez'


3 Réponses :


5
votes
  1. est en sécurité selon la norme.

  2. extrêmement dangereux. Peu de gens en sont conscients, et une personne qui maintient votre fichier d'en-tête pourrait réorganiser les membres avec des conséquences désastreuses.

    Je ne compterais pas dessus.


1 commentaires

Je l'ai mis avec des avertissements de capuchon à blocs dans le fichier d'en-tête.



2
votes

J'aimerais réécrire le code pour rendre le code évident même à un singe.

Un autre problème potentiel ici peut survenir lorsque la classe foo est la classe de base. Le fil commencera sur un objet non entièrement construit. Que se passera-t-il si le constructeur de la classe dérivée échoue? Dans ce cas, il est préférable de déplacer l'exécution du thread hors du constructeur vers start () méthode.


0 commentaires

4
votes

Bien que par la standard c'est sûr, je n'allais pas avec elle.

anecdote: J'ai écrit un threadpool personnalisé sur Windows Studio 2013 . J'ai déclaré la piscine de thread globale. Bien sûr, par la norme , les objets globaux sont destructés après le retour principal. Le destructeur de la piscine de thread a essayé de rejoindre chaque thread, mais hélas! une molette morte. (Vous pouvez lire sur ce problème ici: std :: thread :: joindre () se bloque si appelé après la principale () se ferme lors de l'utilisation de VS2012 RC ). Les états standards très clairement que si un fil est adjoint, il n'ya pas de problème, mais comme vous pouvez le constater, cela n'était pas parfaitement mis en œuvre.

Pourquoi je vous dis ce problème sans rapport? Parce que même les compilateurs et les plates-formes ont des bugs. Les choses subtiles peuvent ne pas être implémentées correctement à 100% aux premières versions de compilateur de support pertinentes.

C'est pourquoi je n'irais pas avec cette idée. En tant que travail autour, je déclare le fil enveloppé dans std :: unique_ptr et initialisez-le dans le corps du constructeur. De cette façon, il n'y a aucune chance qu'elle sera initialisée avant garder_augue . xxx


0 commentaires