Ist es möglich, die Gewindesicherheit nachzuweisen?

9

Kann mit einem Programm, das aus Variablen und Anweisungen besteht, die diese Variablen ändern, und einem Synchronisationsprimitiv (Monitor, Mutex, Java synchronisiert oder C # -Sperre) nachgewiesen werden, dass ein solches Programm threadsicher ist?

Gibt es überhaupt ein formales Modell zur Beschreibung von Dingen wie Thread-Sicherheit oder Rennbedingungen?

Emiswelt
quelle
2
Ja, aber reale Sprachen können nerven, da ihre gleichzeitige Semantik nicht immer genau definiert / festgelegt ist. Auch ist nicht bei jedem Modell alles entscheidbar. Es ist ein weites Feld; google "Concurrency Theory", um einen Eindruck zu bekommen. Insbesondere gibt es eine reichhaltige Theorie über Petri-Netze.
Raphael

Antworten:

9

Es ist schwierig zu beweisen, dass ein Programm "threadsicher" ist. Es ist jedoch möglich, den Begriff "Datenrennen" konkret und formal zu definieren. Außerdem kann festgestellt werden, ob eine Ausführungsablaufverfolgung eines bestimmten Programmlaufs zeitlich proportional zur Größe der Ablaufverfolgung ein Datenrennen aufweist oder nicht. Diese Art der Analyse reicht mindestens bis 1988 zurück: Barton P. Miller, Jong-Deok Choi, "Ein Mechanismus zum effizienten Debuggen paralleler Programme", Conf. auf Prog. Lang. Dsgn. und Impl. (PLDI-1988): 135-144 .

Bei einem Trace einer Ausführung definieren wir zunächst eine Vor-Reihenfolge zwischen Ereignissen in dem Trace. Bei zwei Ereignissen und b , die im selben Thread auftreten, ist a < b oder b < a . (Die Ereignisse auf demselben Thread bilden eine Gesamtreihenfolge, die durch die sequentielle Semantik der Programmiersprache vorgegeben wird.) Synchronisationsereignisse (dies können beispielsweise Mutex-Erfassungen und -Freigaben sein) führen zu einem zusätzlichen Zwischen-Thread, der vor einer Teilreihenfolge auftritt. (Wenn Thread S einen Mutex freigibt und Thread T diesen Mutex abruft, sagen wir, dass die Freigabe erfolgt - vor dem Erwerb.)einbein<bb<einS.T.

Bei zwei Datenzugriffen (Lesen oder Schreiben in Variablen, die keine Synchronisationsvariablen sind) und b , die sich auf demselben Speicherort befinden, aber von verschiedenen Threads stammen und bei denen entweder a oder b eine Schreiboperation ist, sagen wir, dass es eine Daten- gibt. Rennen zwischen a und b, wenn weder a < b noch b < a .einbeinbeinbein<bb<ein

Der C ++ 11-Standard ist ein gutes Beispiel. (Der relevante Abschnitt ist 1.10 in den online verfügbaren Entwurfsspezifikationen.) C ++ 11 unterscheidet zwischen Synchronisationsobjekten (Mutexe und mit einem atomic<>Typ deklarierte Variablen ) und allen anderen Daten. Die C ++ 11-Spezifikation besagt, dass der Programmierer über die Datenzugriffe in einer Spur eines Multithread-Programms argumentieren kann, als ob sie sequentiell konsistent wären, wenn die Datenzugriffe alle datenrennfrei sind.

Das Helgrind-Tool (Teil von Valgrind) führt diese Art der datenbasierten Erkennung durch, bevor mehrere kommerzielle Tools (z. B. Intel Inspector XE) verwendet werden. Die Algorithmen in modernen Tools basieren darauf, dass Vektoruhren mit jedem Thread und jeder Synchronisation verknüpft bleiben Objekt. Ich denke, diese Technik der Verwendung von Vektoruhren zur Erkennung von Datenrennen wurde von Michiel Ronsse entwickelt. Koen De Bosschere: "RecPlay: ein vollständig integriertes praktisches Aufzeichnungs- / Wiedergabesystem", ACM Trans. Comput. Syst. 17 (2): 133-152, 1999 .

Wanderlogik
quelle
6

Von der praktischen Seite her gibt es ein Verifizierungssystem VCC, mit dem die Thread-Sicherheit von C-Programmen formal nachgewiesen werden kann.

Dies ist ein Zitat von der Website:

VCC unterstützt Parallelität - Sie können VCC verwenden, um Programme zu überprüfen, die sowohl grobkörnige als auch feinkörnige Parallelität verwenden. Sie können es sogar verwenden, um Ihre Grundelemente für die Parallelitätskontrolle zu überprüfen. Das implizite Überprüfen einer Funktion garantiert ihre Thread-Sicherheit in jeder gleichzeitigen Umgebung, in der die Verträge für ihre Funktionen und Datenstrukturen eingehalten werden.

Anton Dergunov
quelle
2
Wie funktioniert es? Was ist das zugrunde liegende formale Modell? Beachten Sie, dass das OP nicht (nur) nach einem Werkzeug fragt!
Raphael
1

Dies ist ein sehr schwieriger Bereich, um die Programmkorrektheit sicherzustellen, soweit die Rennbedingungen ausgeschlossen sind, eine Art "Achillesferse" der Parallelverarbeitung. Der beste Ansatz für die Programmkorrektheit besteht im Allgemeinen darin, Grundelemente auf niedriger Ebene zu vermeiden und mit Entwurfsmustern auf höherer Ebene (z. B. aus Bibliotheken) zu arbeiten, die die Thread-Synchronisation sicherstellen. Es gibt ein CSP- Modell , das sequentielle Prozesse von Hoare kommuniziert und einige Beweise für die Richtigkeit aufweist, da sich Entwickler auf das "Framework" beschränken. Es hat eine gewisse konzeptionelle Ähnlichkeit und chronologische Entstehung / Überlappung mit Unix "Pipes and Filters ", obwohl (noch?) Keine direkte Verbindung zwischen beiden gefunden wurde.

Zwei weitere Frameworks, die versuchen, die Parallelisierungskorrektheit durch Entwurfsmuster zu verbessern, und die die meisten Standard- / bekannten Algorithmen / Entwurfsmuster für diesen Zweck aufweisen:

vzn
quelle
1
Dies mag ein guter (Programmier-) Rat sein, beantwortet aber die (CS) -Frage überhaupt nicht.
Raphael
1
?!? Die Kritik ist überhaupt nicht spezifisch
vzn