Maison >développement back-end >C++ >Pourquoi mon programme multithread optimisé se bloque-t-il lors de l'utilisation d'un indicateur booléen non atomique ?

Pourquoi mon programme multithread optimisé se bloque-t-il lors de l'utilisation d'un indicateur booléen non atomique ?

Barbara Streisand
Barbara Streisandoriginal
2024-12-28 00:33:19293parcourir

Why Does My Optimized Multithreaded Program Freeze When Using a Non-Atomic Boolean Flag?

Malheurs d'optimisation du programme multithread

Dans votre code, vous avez un programme multithread dans lequel un thread séparé incrémente un compteur pendant que le thread principal attend une seconde, puis définit un indicateur pour signaler au compteur de s'arrêter. Cependant, lors de l'exécution en mode optimisé (-O1 -O3), le programme reste bloqué sans imprimer de résultat.

Le coupable : l'accès aux variables non atomiques

Le le problème vient de la variable "terminée", qui est un simple bool auquel plusieurs threads accèdent simultanément sans aucune garantie de synchronisation ou d'atomicité. Lorsqu'elle est accessible simultanément, cette variable peut conduire à un comportement non défini (UB).

Solution : utilisez std::atomic

Pour résoudre ce problème, la variable "terminée" doit être déclaré comme un type atomique, tel que std::atomic. std::atomic fournit des garanties d'atomicité, garantissant que l'accès à la variable est synchronisé et bien défini.

Code révisé :

#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>

Explication :

Dans le code révisé, la variable "terminé" est déclarée comme std::atomic, garantissant un accès atomique. Cela évite le comportement indéfini qui provoquait le gel du programme.

Remarque sur l'optimisation

En mode optimisé, le compilateur peut effectuer des optimisations agressives qui peuvent causer des problèmes si les données n’est pas correctement synchronisé. En utilisant std::atomic, vous demandez explicitement au compilateur de conserver l'atomicité de la variable "terminée", même dans les versions optimisées.

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