Why Does a Multithreading Program Get Stuck in Optimized Mode?
This article explores an issue commonly encountered in multithreaded programs, where the program gets stuck in optimized mode (-O1, -O2, -O3) but behaves normally in unoptimized mode (-O0).
Consider the following multithreaded program written in 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>
When running this program in debug mode (unoptimized) or with GCC's -O0 flag, it typically behaves as expected and prints the result after 1 second. However, when compiled in release mode or with higher optimization levels (-O1, -O2, -O3), the program gets stuck and does not print anything.
The issue lies in the shared variable finished, which is non-atomic and non-guarded. The optimizing compiler reorders the memory access instructions, causing multiple threads to access this variable concurrently, leading to undefined behavior. To fix this, we should use an atomic variable for finished.
Here is the corrected code:
#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>
With this fix, the program will behave correctly even in optimized mode. It demonstrates the importance of using atomic variables in multithreaded programs to prevent data races and undefined behavior.
The above is the detailed content of Why Do Multithreaded Programs Freeze Under Compiler Optimization?. For more information, please follow other related articles on the PHP Chinese website!