Betrachten Sie das folgende Code-Schnipsel:
%Vor%Fragen:
Ist es möglich, dass "flag" immer 0 für den Haupt-Thread ist (und es wird wegen einer Compiler-Optimierung in der do / while-Schleife hängengeblieben?
Macht der 'volatile' Modifikator einen Unterschied?
Wenn die Antwort "hängt von einer Funktion des Compilers ab" ist, gibt es welche So kann ich mit einem Konfigurationsskript unter diesem Feature nachsehen Kompilierzeit?
Da Sie annehmen können, dass das Laden einer ausgerichteten int
eine atomare Operation ist, besteht die einzige Gefahr mit Ihrem Code im Optimierer: Ihr Compiler darf alle bis auf die ersten Lesevorgänge von flag
in% co_de optimieren %, ich. e. um deinen Code in
Es gibt zwei Möglichkeiten, wie Sie sicherstellen können, dass dies nicht geschieht: 1. Machen Sie main()
volatile, was eine schlechte Idee ist, weil es ziemlich viel unerwünschten Overhead enthält und 2. Einführung der notwendigen Speicherbarrieren. Aufgrund der Unteilbarkeit beim Lesen von flag
und der Tatsache, dass Sie nur den Wert von int
nach der Änderung interpretieren wollen, sollten Sie nur mit einer Compilerschranke vor der Schleifenbedingung wie folgt fertig werden:
Das hier verwendete flag
ist sehr leicht, es ist die billigste aller verfügbaren Barrieren.
Dies ist nicht genug, wenn Sie andere Daten analysieren möchten, die geschrieben werden, bevor barrier()
ausgelöst wird, weil Sie möglicherweise noch veraltete Daten aus dem Speicher laden (weil die CPU sich entschieden hat, den Wert vorab abzurufen). Für eine umfassende Diskussion von Gedächtniszäunen, ihrer Notwendigkeit und ihrer Verwendung siehe Ссылка
Schließlich sollten Sie beachten, dass der andere Autorenthread flag
jederzeit ändern kann, nachdem die flag
-Schleife beendet wurde. Also sollten Sie seinen Wert sofort in eine Schattenvariable wie folgt kopieren:
Der Code funktioniert wahrscheinlich so wie er ist, ist aber etwas fragil. Zum einen hängt es davon ab, ob die Lese- und Schreibvorgänge in flag
atomar auf dem verwendeten Prozessor sind (und dass die Ausrichtung von flag
ausreichend ist).
Ich würde empfehlen, entweder eine Lesesperre zu verwenden, um den Wert von flag
zu lesen, oder die Funktionalität der von Ihnen verwendeten Threading-Bibliothek zu verwenden, um flag
richtig atomar zu machen.
Tags und Links c multithreading thread-safety compiler-optimization pthreads