Heim >Backend-Entwicklung >C++ >Warum friert mein optimiertes Multithread-Programm ein, wenn ein nicht-atomares boolesches Flag verwendet wird?

Warum friert mein optimiertes Multithread-Programm ein, wenn ein nicht-atomares boolesches Flag verwendet wird?

Barbara Streisand
Barbara StreisandOriginal
2024-12-28 00:33:19296Durchsuche

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

Probleme bei der Multithreading-Programmoptimierung

In Ihrem Code haben Sie ein Multithread-Programm, bei dem ein separater Thread einen Zähler erhöht, während der Haupt-Thread darauf wartet eine Sekunde lang und setzt dann ein Flag, um dem Zähler-Thread zu signalisieren, dass er angehalten wird. Wenn das Programm jedoch im optimierten Modus (-O1 -O3) ausgeführt wird, bleibt es hängen, ohne eine Ausgabe zu drucken.

Der Übeltäter: Zugriff auf nicht-atomare Variablen

Der Das Problem entsteht durch die Variable „fertig“, bei der es sich um einen einfachen Bool-Wert handelt, auf den mehrere Threads gleichzeitig zugreifen, ohne dass Synchronisierungs- oder Atomizitätsgarantien vorliegen. Bei gleichzeitigem Zugriff kann diese Variable zu undefiniertem Verhalten (UB) führen.

Lösung: Verwenden Sie std::atomic

Um dieses Problem zu beheben, sollte die Variable „fertig“ sein als atomarer Typ deklariert werden, z. B. std::atomic. std::atomic bietet Atomizitätsgarantien und stellt sicher, dass der Zugriff auf die Variable synchronisiert und wohldefiniert ist.

Überarbeiteter 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>

Erklärung:

Im überarbeiteten Code wird die Variable „fertig“ als deklariert std::atomic, um den atomaren Zugriff sicherzustellen. Dadurch wird das undefinierte Verhalten verhindert, das zum Einfrieren des Programms geführt hat.

Hinweis zur Optimierung

Im optimierten Modus führt der Compiler möglicherweise aggressive Optimierungen durch, die Probleme bei den Daten verursachen können ist nicht richtig synchronisiert. Durch die Verwendung von std::atomic weisen Sie den Compiler explizit an, die Atomizität der „fertigen“ Variablen auch in optimierten Builds beizubehalten.

Das obige ist der detaillierte Inhalt vonWarum friert mein optimiertes Multithread-Programm ein, wenn ein nicht-atomares boolesches Flag verwendet wird?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn