Ist es sicher, nach einer Variablen zu suchen, die von anderen Threads in einem C-Programm geschrieben wurde?

8

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?

Thiago de Arruda 19.01.2014, 13:06
quelle

3 Antworten

0

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

umzuwandeln %Vor%

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:

%Vor%

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:

%Vor%     
cmaster 19.01.2014, 18:26
quelle
2

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.

    
James Hopkin 19.01.2014 18:19
quelle
0

Es ist möglich, dass while vor den Threads ausgeführt wird ... Sie müssen die Ausführung des Threads vorher mit pthread_join ()

abwarten     
Daniele 19.01.2014 13:15
quelle