Est-ce que volatile int en C est aussi bon que std :: atomic de C ++ 0x?

J’ai besoin d’avoir des variables atomiques dans mon programme. Auparavant, j’utilisais std::atomic , mais la plate-forme sur laquelle je travaille ne dispose actuellement pas d’un compilateur g ++ prenant en charge C ++ 0x. J’ai utilisé volatile int et cela semble fonctionner, car je n’ai pas encore rencontré de problème de concurrence critique dans le système multicœur sur lequel je le teste.

Ma question est si volatile int est atomique comme std::atomic ? En outre, cela crée-t-il des barrières de mémoire (que j’ai également besoin)?

    Je vous ai vu poser des questions sur GCC dans certains commentaires.

    Fonctions intégrées de GCC pour l’access à la mémoire atomique

    Non, volatile n’a rien à voir avec le multithreading. Il n’impose pas de barrière de mémoire (bien que certains compilateurs puissent quand même choisir de l’append de toute façon ) et ne donne aucune garantie quant à la réorganisation en lecture / écriture des objects non volatils.

    volatile été ajouté pour prendre en charge l’écriture dans les registres d’E / S matérielles mappées en mémoire, et dans les cas où il est important que votre écriture ne soit pas optimisée, mais sans garantie d’ordre précis. des lectures / tentatives non volatiles sont requirejses.

    Vous voudrez peut-être aussi lire ceci

    Les variables volatiles n’impliquent PAS de barrières de mémoire et n’ont pas les opérations exchange ou compare_exchange_* de std::atomic . Ils évitent au compilateur de soulever une charge dans plusieurs charges au niveau du code machine (et inversement, et similaire pour les magasins), mais c’est tout.

    Vous pouvez être intéressé par ces articles:

    • volatile considéré comme nuisible
    • Volatile: presque inutile pour la programmation multi-thread

    Si vous n’avez pas std::atomic , vous pouvez utiliser boost :: atomic ou les primitives de barrière de bas niveau et d’opération atomique offertes par le compilateur que vous utilisez.

    Avant C ++ 0x, le langage ne connaissait pas les threads et n’empêchait donc pas les access multiples. Le déclarer volatil aidera certains, mais cela n’empêchera pas les courses.

    Voir http://en.wikipedia.org/wiki/Volatile_variable pour plus de détails.

    Pour vraiment rendre les opérations atomiques, vous devez utiliser le mécanisme de locking fourni par votre bibliothèque de threads (threads win32, pthreads, etc.).

    Il y a un bon résumé des diffs ici , de Herb Sutter. En résumé (couper et coller):

    Pour écrire en toute sécurité un code sans verrou qui communique entre les threads sans utiliser de verrou, utilisez plutôt 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 mémoire ayant une sémantique inhabituelle, utilisez des variables non optimisables: ISO C / C ++ volatile. Rappelez-vous que les lectures et les écritures de ces variables ne sont pas nécessairement atomiques.

    volatile indique essentiellement au compilateur qu’il ne peut pas présumer de ce qu’il y a dans un emplacement de mémoire particulier. Par exemple

     bool test = true; while(!test) { /* do something (eg wait) */ } 

    le compilateur peut optimiser tout le while car il suppose que le test est toujours vrai. Si toutefois le test doit à un moment être mis à jour ailleurs (par exemple, du matériel ou un autre thread), nous ne voulons pas que le compilateur présume qu’il sait ce qui se trouve dans le test . Nous pouvons dire au compilateur qu’en utilisant volatile .

    Comme le disent les autres réponses, cela ne donne aucune garantie quant à l’ordre dans lequel les objects accèdent à l’emplacement mémoire.

    Ps j’ai volé sans vergogne cet exemple quelque part mais je ne me souviens pas où je l’ai vu.