web-dev-qa-db-fra.com

C ++ std :: atomic vs Boost atomic

Dans mon application, j'ai un int et une variable bool, qui sont accessibles (écriture/lecture multiples) par plusieurs threads. Actuellement, j'utilise deux mutex, un pour int et un pour bool pour protéger ces variables.

J'ai entendu parler de l'utilisation de variables et d'opérateurs atomiques pour écrire un programme multi-thread sans verrouillage. Mes questions sont

  1. Quelle est la définition des variables et opérateurs atomiques?
  2. Quelle est la principale différence entre std :: atomic et boost/atomic.hpp? Lequel est le plus standard ou le plus populaire?
  3. Ces bibliothèques dépendent-elles de la plate-forme? J'utilise gnu gcc 4.6 sur Linux pour le moment, mais idéalement, il doit être multiplateforme. J'ai entendu dire que la définition de "atomique" dépend également du matériel. Quelqu'un peut-il également expliquer cela?
  4. Quelle est la meilleure façon de partager une variable booléenne entre plusieurs threads? Je préférerais ne pas utiliser le mot clé "volatile".

Ces codes sont-ils thread-safe?

double double_m; // double_m is only accessed by current thread.
std::atomic<bool> atomic_bool_x;
atomic_bool_x = true && (double_m > 12.5);

int int_n; // int_n is only accessed by current thread.
std::atomic<int> atomic_int_x;
std::atomic<int> atomic_int_y;
atomic_int_y = atomic_int_x * int_n;
28
2607

Je ne suis pas un expert ou quoi que ce soit, mais voici ce que je sais:

  1. std::atomic dit simplement que l'appel simultané de load et store (et quelques autres opérations) est bien défini. Une opération atomique est indivisible - rien ne peut se produire "entre les deux".
  2. Je suppose std::atomic est basé sur boost::atomic. Si vous le pouvez, utilisez std, sinon utilisez boost.
  3. Ils sont tous les deux portables, le std étant complètement ainsi, cependant votre compilateur devra prendre en charge C++ 11
  4. Probable std::atomic_bool. Vous ne devriez pas avoir besoin d'utiliser volatile.

De plus, je crois que load/store diffère de operator=/operator T seulement load/store sont atomiques.

Ça ne fait rien. J'ai vérifié la norme et il semble que les opérateurs soient définis en termes de load/store/etc, mais ils peuvent renvoyer des choses différentes.

Lectures complémentaires:

17
Pubby

La volatilité est orthogonale à ce que vous utilisez pour implémenter l'atomique. En C++, il indique au compilateur qu'il n'est pas sûr d'effectuer des optimisations avec cette variable. Herb Sutters le dit:

Pour écrire en toute sécurité du code sans verrou qui communique entre les threads sans utiliser de verrous, préférez utiliser des variables atomiques ordonnées: Java/.NET volatile, C++ 0x atomique et C-compatible atomic_T.

Pour communiquer en toute sécurité avec du matériel spécial ou une autre mémoire ayant une sémantique inhabituelle, utilisez des variables non optimisables: ISO C/C++ volatile. N'oubliez pas cependant que la lecture et l'écriture de ces variables ne sont pas nécessairement atomiques.

Enfin, pour exprimer une variable qui a à la fois une sémantique inhabituelle et possède une ou toutes les garanties d'atomicité et/ou de commande nécessaires pour un codage sans verrouillage, seul le projet de norme ISO C++ 0x fournit un moyen direct de l'orthographier: atomique volatile .

(depuis http://drdobbs.com/article/print?articleId=212701484&siteSectionName=parallel )

7
  1. Voir std :: modèle de classe atomique
  2. std::atomic est standard depuis C++ 11, et les éléments Boost sont plus anciens. Mais comme c'est standard maintenant, je préfère std::atomic.
  3. ?? Vous pouvez utiliser std::atomic avec chaque compilateur C++ 11 sur chaque plate-forme souhaitée.
  4. Sans plus d'informations ...

    std :: atomic;

2
cooky451

Je crois std::atomic (C++ 11) et boost.atomic sont équivalents. Si std::atomic n'est pas encore pris en charge par votre compilateur, utilisez boost::atomic.

1
01100110