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!