Question

J'ai une application multi-thread C ++ qui effectue le rendu 3D avec la bibliothèque OpenSceneGraph. Je prévois de lancer la boucle de rendu d'OSG en tant que thread séparé à l'aide de boost :: threads, en transmettant une structure de données contenant un état partagé au thread. J'essaie d'éviter tout ce qui est trop lourd (comme les mutex) pour la synchronisation, car la boucle de rendu doit être assez serrée et OSG lui-même tente de ne pas avoir à se verrouiller. La plupart des états partagés sont définis avant le démarrage du thread et ne sont jamais modifiés. J'ai des données à modifier, que je prévois de mettre en mémoire tampon. Cependant, j'ai un simple booléen pour signaler au thread de suspendre le rendu, puis de le reprendre, et un autre pour le tuer. Dans les deux cas, le thread d'application définit le booléen et le thread de rendu ne le lit que. Dois-je synchroniser l'accès à ces bools? Autant que je sache, le pire qui pourrait arriver est que la boucle de rendu continue pendant une image supplémentaire avant la suspension ou la fermeture.

Était-ce utile?

La solution

Dans C ++ 11 et versions ultérieures, qui dispose d'une concurrence définie par les normes, utilisez std::atomic<bool> à cette fin. De http://fr.cppreference.com/w/cpp/atomic/atomic:

  

Si un thread écrit sur un objet atomique pendant qu'un autre le lit, le comportement est bien défini (voir le modèle de mémoire pour plus de détails sur les courses de données).

L'ancienne réponse suivante peut avoir été vraie à un moment donné avec certains compilateurs et certains environnements d'exploitation, mais il ne faut pas s'y fier aujourd'hui:

Vous avez raison, dans ce cas, vous n'avez pas besoin de synchroniser les bools. Vous devez cependant les déclarer volatile pour vous assurer que le compilateur les lit réellement à chaque fois dans la mémoire, au lieu de mettre en cache la lecture précédente dans un fil (explication simplifiée, mais qui devrait l'être à cette fin).

La question suivante contient plus d'informations à ce sujet: C ++ Thread, données partagées

Autres conseils

Pourquoi ne pas simplement utiliser une variable verrouillée ?

En ce qui concerne C ++ 11 et versions ultérieures, il est enfin compatible avec les threads et indique clairement que modifier un bool (ou une autre variable non atomique) dans un thread et y accéder en même temps dans un autre est un comportement indéfini. Dans votre cas, utiliser std::atomic<bool> devrait suffire à corriger le programme, ce qui vous évitera d’utiliser des verrous.
N'utilisez pas volatile . Cela n'a rien à voir avec les discussions. Pour plus de discussion, consultez Puis-je lire un bool variable dans un thread sans mutex?

Je ne pense pas que vous ayez besoin d'un mutex à part entière, même si le thread de rendu doit être occupé à attendre dans l'état "suspendu" si vous n'utilisez pas d'objet de synchronisation prenant en charge une primitive d’attente.

Toutefois, vous devriez envisager d’utiliser les différentes primitives d’échange interconnectées (InterlockedExchange sous Windows). Non pas parce que les lectures / écritures de bool ne sont pas atomiques, mais pour éviter tout comportement étrange, le compilateur réordonne les accès à la mémoire sur un seul thread.

Ce fil contient un peu plus d'informations et de discussions sur la sécurité des threads, en particulier pour les types de données simples:

Comment créer un thread modèle singleton sécurisé sous Windows?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top