マルチスレッド プログラムの最適化の問題
コードには、メイン スレッドが待機している間に別のスレッドがカウンターをインクリメントするマルチスレッド プログラムがあります。 1 秒後にフラグを設定して、カウンタ スレッドに停止の信号を送ります。ただし、最適化モード (-O1 -O3) で実行すると、プログラムは何も出力せずにスタックします。
犯人: 非アトミック変数アクセス
この問題は、「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 を使用すると、最適化されたビルドであっても、「finished」変数のアトミック性を維持するようにコンパイラーに明示的に指示できます。
以上が非アトミック ブール フラグを使用すると、最適化されたマルチスレッド プログラムがフリーズするのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。