ホームページ >バックエンド開発 >C++ >非アトミック ブール フラグを使用すると、最適化されたマルチスレッド プログラムがフリーズするのはなぜですか?

非アトミック ブール フラグを使用すると、最適化されたマルチスレッド プログラムがフリーズするのはなぜですか?

Barbara Streisand
Barbara Streisandオリジナル
2024-12-28 00:33:19296ブラウズ

Why Does My Optimized Multithreaded Program Freeze When Using a Non-Atomic Boolean Flag?

マルチスレッド プログラムの最適化の問題

コードには、メイン スレッドが待機している間に別のスレッドがカウンターをインクリメントするマルチスレッド プログラムがあります。 1 秒後にフラグを設定して、カウンタ スレッドに停止の信号を送ります。ただし、最適化モード (-O1 -O3) で実行すると、プログラムは何も出力せずにスタックします。

犯人: 非アトミック変数アクセス

この問題は、「finished」変数によって発生します。この変数は、同期やアトミック性が保証されずに、複数のスレッドによって同時にアクセスされる単純なブール値です。同時にアクセスすると、この変数は未定義の動作 (UB) を引き起こす可能性があります。

解決策: std::atomic を使用します

これに対処するには、「finished」変数を使用する必要があります。 std::atomic などのアトミック型として宣言できます。 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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。