Maison >développement back-end >C++ >Pourquoi mon programme multithread se bloque-t-il en mode optimisé mais fonctionne-t-il en -O0 ?

Pourquoi mon programme multithread se bloque-t-il en mode optimisé mais fonctionne-t-il en -O0 ?

Patricia Arquette
Patricia Arquetteoriginal
2024-12-29 22:02:30670parcourir

Why Does My Multithreaded Program Stall in Optimized Mode But Work in -O0?

Le programme multithreading se bloque en mode optimisé mais s'exécute normalement en -O0

Ce problème provient d'un programme multithreading où les variables partagées ne sont pas atomiques. Plus précisément, le problème réside dans la variable booléenne terminée à laquelle deux threads accèdent sans aucune synchronisation ni atomicité.

En mode optimisé, le compilateur suppose que les variables partagées accessibles par plusieurs threads sont protégées. Cependant, dans ce programme, finish est déclaré comme un booléen normal, ce qui le rend non atomique. Cela permet au compilateur d'optimiser les mécanismes de synchronisation essentiels au fonctionnement multithread.

Pour résoudre ce problème, terminé doit être déclaré comme std::atomic. Ce type fournit des opérations de lecture et d'écriture atomiques, garantissant que les accès simultanés à la variable restent bien définis et cohérents.

Code fixe :

#include <iostream>
#include <future>
#include <atomic>

static std::atomic<bool> finished = false;

int func()
{
    size_t i = 0;
    while (!finished)
        ++i;
    return i;
}

int main()
{
    auto result = std::async(std::launch::async, func);
    std::this_thread::sleep_for(std::chrono::seconds(1));
    finished = true;
    std::cout << "result = " << result.get();
    std::cout << "\nmain thread>

Démo en direct : coliru

Considérations supplémentaires :

  • Les variables volatiles ne peuvent à elles seules garantir l'atomicité. Bien qu'ils empêchent le compilateur d'optimiser les opérations de lecture/écriture, ils ne fournissent pas de barrières de mémoire ni de primitives de synchronisation.
  • Les compilateurs modernes sont très agressifs en matière d'optimisation. Il est important d'indiquer explicitement les régions de mémoire partagée et les exigences de synchronisation des ressources pour éviter tout comportement inattendu.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn