Maison >développement back-end >C++ >Pourquoi les programmes multithread se bloquent-ils sous l'optimisation du compilateur ?

Pourquoi les programmes multithread se bloquent-ils sous l'optimisation du compilateur ?

Linda Hamilton
Linda Hamiltonoriginal
2024-12-13 16:31:15870parcourir

Why Do Multithreaded Programs Freeze Under Compiler Optimization?

Pourquoi un programme multithread reste-t-il bloqué en mode optimisé ?

Cet article explore un problème couramment rencontré dans les programmes multithread, où le programme reste bloqué en mode optimisé (- O1, -O2, -O3) mais se comporte normalement en mode non optimisé (-O0).

Considérez ce qui suit programme multithread écrit en C :

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

Lors de l'exécution de ce programme en mode débogage (non optimisé) ou avec l'indicateur -O0 de GCC, il se comporte généralement comme prévu et imprime le résultat après 1 seconde. Cependant, lorsqu'il est compilé en mode release ou avec des niveaux d'optimisation plus élevés (-O1, -O2, -O3), le programme reste bloqué et n'imprime rien.

Le problème réside dans la variable partagée terminée, qui est non atomique et non gardé. Le compilateur d'optimisation réorganise les instructions d'accès à la mémoire, ce qui oblige plusieurs threads à accéder simultanément à cette variable, conduisant à un comportement indéfini. Pour résoudre ce problème, nous devons utiliser une variable atomique pour terminé.

Voici le code corrigé :

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

Avec ce correctif, le programme se comportera correctement même en mode optimisé. Cela démontre l'importance de l'utilisation de variables atomiques dans les programmes multithread pour éviter les courses de données et les comportements indéfinis.

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