多執行緒程式最佳化問題
在您的程式碼中,您有一個多執行緒程序,其中一個單獨的執行緒在主執行緒等待時遞增計數器一秒鐘,然後設定一個標誌來指示計數器線程停止。然而,當在最佳化模式(-O1 -O3)下運行時,程式會卡住而不會列印任何輸出。
罪魁禍首:非原子變量訪問
The問題源於“finished”變量,它是一個簡單的布爾值,由多個線程同時訪問,沒有任何同步或原子性保證。並發存取時,此變數可能會導致未定義的行為 (UB)。
解決方案:使用std::atomic
要解決此問題,「finished」變數應該被宣告為原子類型,例如std::atomic
修訂的程式碼:
#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>
說明:
在修改後的程式碼中,「finished變數」被聲明為std::atomic
最佳化注意事項
在最佳化模式下,編譯器可能會執行激進的最佳化,如果資料未正確同步。透過使用 std::atomic,您可以明確指示編譯器維護「完成」變數的原子性,即使在最佳化建置中也是如此。
以上是為什麼我的優化多執行緒程式在使用非原子佈林標誌時會凍結?的詳細內容。更多資訊請關注PHP中文網其他相關文章!