Heim >Backend-Entwicklung >C++ >Warum frieren Multithread-Programme bei Compiler-Optimierung ein?

Warum frieren Multithread-Programme bei Compiler-Optimierung ein?

Linda Hamilton
Linda HamiltonOriginal
2024-12-13 16:31:15870Durchsuche

Why Do Multithreaded Programs Freeze Under Compiler Optimization?

Warum bleibt ein Multithreading-Programm im optimierten Modus hängen?

In diesem Artikel wird ein häufig bei Multithread-Programmen auftretendes Problem untersucht, bei dem das Programm im optimierten Modus hängen bleibt (- O1, -O2, -O3), verhält sich aber im nicht optimierten Modus (-O0) normal.

Bedenken Sie Folgendes Folgendes in C geschriebene Multithread-Programm:

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>

Wenn dieses Programm im Debug-Modus (nicht optimiert) oder mit dem Flag -O0 von GCC ausgeführt wird, verhält es sich normalerweise wie erwartet und gibt das Ergebnis nach 1 Sekunde aus. Beim Kompilieren im Release-Modus oder mit höheren Optimierungsstufen (-O1, -O2, -O3) bleibt das Programm jedoch hängen und gibt nichts aus.

Das Problem liegt darin, dass die gemeinsam genutzte Variable fertig ist nichtatomar und nicht bewacht. Der optimierende Compiler ordnet die Speicherzugriffsanweisungen neu, was dazu führt, dass mehrere Threads gleichzeitig auf diese Variable zugreifen, was zu undefiniertem Verhalten führt. Um dies zu beheben, sollten wir eine atomare Variable für „Fertig“ verwenden.

Hier ist der korrigierte 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>

Mit diesem Fix verhält sich das Programm auch im optimierten Modus korrekt. Es zeigt, wie wichtig es ist, atomare Variablen in Multithread-Programmen zu verwenden, um Datenrennen und undefiniertes Verhalten zu verhindern.

Das obige ist der detaillierte Inhalt vonWarum frieren Multithread-Programme bei Compiler-Optimierung ein?. 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