2
votes

C ++ 11: la variable Mutex et condition ne peut pas être copiée

Je suis nouveau dans C ++ 11 et j'utilise le threading. Je suis tombé sur un scénario dans lequel il n'est pas possible de copier des objets variables mutex & condition. Le code est comme ça ....

int main ()
{
    mutex m;
    condition_variable cv;
    //Initialize mutex & cv
    producer prod(m, cv);
}

Lorsque vous essayez de copier les variables dans le constructeur, cela donne l'erreur. On dirait que le constructeur de copie est configuré pour supprimer pour mutex et cv.

Y a-t-il un moyen de surmonter cela? Je veux une classe de producteur et de consommateur et puis passer le mutex & cv de la fonction main .

donc fondamentalement l'appel de la fonction principale devrait ressembler à .... p >

class producer {

   public: 
      producer(mutex m, condition_variable cv) 
      {
           mut = m;    // ERROR
           cvar = cv;   // ERROR
       }

    private:
         mutex mut;
         condition_variable cvar;
}


3 commentaires

Pensez au genre d'horreurs qui résulteraient du fait d'avoir plusieurs copies d'un mutex. Vous pouvez construire l'intérieur autour de quelque chose comme un pointeur partagé afin que les copies référencent toutes les mêmes mutex-tripes sous-jacentes, mais cela pénalise tous ceux qui veulent simplement utiliser un mutex sans le faire passer.


Un mutex est destiné à sécuriser une ressource. Plutôt que de passer le mutex, envisagez d'encapsuler la ressource et le mutex dans une classe et de transmettre une instance de cette classe. À la fin de la journée, vous aurez le même problème avec le mutex non copiable, tout comme l'objet d'encapsulation, mais l'intention est mieux décrite et vous pouvez utiliser la classe pour empêcher l'accès à la ressource sans acquérir le mutex .


Comment écrire vos membres spéciaux lorsque vous avez un membre de données mutex : stackoverflow.com/a/29988626/576911


3 Réponses :


2
votes

Non, ce n'est pas possible. Des fonctionnalités ont été ajoutées en C ++ pour activer cette fonctionnalité (sans copie).

Si vous pensez à l'implémentation, changez-vous une sorte d'objet noyau? Est-ce que ce sera pareil. Probablement pas. C'est par conception.


0 commentaires

1
votes

Vous voudrez stocker des références ou des pointeurs vers le mutex et condition_variable.

class producer {
public: 
  producer(mutex & m, condition_variable & cv) 
    : _mut{m}
    , _cvar{cv}
  {
  }

private:
     mutex & mut;
     condition_variable & cvar;
};

Vous pouvez utiliser std :: shared_ptr s, car cela permet à vos instances d'avoir une forte propriété du mutex et de la condition_variable , mais c'était plus rapide à taper.

p>


1 commentaires

Il y a un inconvénient à cette approche: les références ne peuvent pas être réinstallées, donc producteur ne peut pas être attribué. Peut ne pas être un problème selon votre cas d'utilisation.



1
votes

C'est impossible de par sa conception.

Que signifie copier un mutex? Que doit-il faire?

Supposons que vous attendiez un mutex A et qu'un corps copie le mutex A vers le mutex B. Attendez-vous toujours A ou B? ou pour les deux? Non. Vous devriez toujours attendre A. Donc, un autre mutex B ne peut pas être une copie de A. La copie est donc supprimée.

L'opération de déplacement a du sens, mais comme les mutex sont alloués statiquement, il est impossible de les déplacer sans changer leurs adresses - ce qui devient un cauchemar pour quiconque attend le mutex. Ainsi, l'opération de déplacement est également supprimée.

Les mêmes critères s'appliquent aux variables de condition.

Pour surmonter ces problèmes, vous pouvez utiliser des pointeurs vers des mutex et des variables de condition. Dites, stockez-les sous std::shared_ptr et std::shared_ptr si vous voulez une conception simple.


0 commentaires