首頁 >後端開發 >C++ >為什麼多執行緒程式在編譯器最佳化下會凍結?

為什麼多執行緒程式在編譯器最佳化下會凍結?

Linda Hamilton
Linda Hamilton原創
2024-12-13 16:31:15870瀏覽

Why Do Multithreaded Programs Freeze Under Compiler Optimization?

為什麼多執行緒程式會陷入最佳化模式?

本文探討了多執行緒程式中常見的問題,即程式陷入最佳化模式(- O1、-O2、-O3),但在未最佳化模式 (-O0) 下表現正常。

考慮以下用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>

在偵錯模式(未最佳化)或使用GCC 的-O0 標誌執行此程式時,它通常會按預期運行並在1 秒後列印結果。然而,當在發布模式或更高的最佳化等級(-O1、-O2、-O3)下編譯時,程式會卡住並且不列印任何內容。

問題在於共享變數finished,即非原子且不受保護。最佳化編譯器對記憶體存取指令重新排序,導致多個執行緒同時存取該變量,從而導致未定義的行為。要解決此問題,我們應該使用完成的原子變數。

這是修正後的程式碼:

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

透過此修復,即使在最佳化模式下,程式也將正確運作。它演示了在多線程程式中使用原子變數來防止資料爭用和未定義行為的重要性。

以上是為什麼多執行緒程式在編譯器最佳化下會凍結?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn