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
Libérer: 2024-12-13 16:31:15
original
873 Les gens l'ont consulté

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>
Copier après la connexion

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>
Copier après la connexion

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!

source:php.cn
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal