Boost shared_lock. Vorgezogen lesen?

8

Ich habe die Boost-Bibliothek (Version 1.45) für eine Lese- / Schreibsperre ausprobiert. Als ich meine Tests darauf durchführte, schien es so, als ob shared_ptr meine Leser-Threads vorzog, d. H. Wenn mein Schreiber versuchte, die Sperre für seine Operation zu übernehmen, stoppte er keine nachfolgenden Lesevorgänge.

Ist es im Boost möglich, dieses Verhalten zu ändern?

%Vor%

Und hier ist die Ausgabe jedes Mal: ​​

Arbeitete ihre Arbeit zu Ende Gearbeitet hat ihre Arbeit beendet Gearbeitet hat ihre Arbeit beendet Gearbeitet hat ihre Arbeit beendet Grabbed exklusive Sperre, System zu töten ALLE ARBEITEN TÖTEN

Meine Anforderung

Wenn der Verfasser versucht hat, eine exklusive Sperre zu ergattern, möchte ich, dass alle vorherigen Lesevorgänge beendet werden. Und dann alle nachfolgenden Leseoperationen zu blockieren.

    
anoneironaut 22.08.2012, 22:43
quelle

2 Antworten

19

Ich bin ein wenig zu spät zu dieser Frage, aber ich glaube, ich habe einige relevante Informationen.

Die Vorschläge von shared_mutex für das C ++ - Committee, auf denen die Boost-Bibliotheken basieren, haben absichtlich keine API angegeben, um den Lesern oder Schreibern Priorität zu geben. Das liegt daran, dass Alexander Terekhov vor etwa einem Jahrzehnt einen Algorithmus vorgeschlagen hat, der vollkommen fair ist. Es lässt das Betriebssystem entscheiden, ob der nächste Thread, um den Mutex zu erhalten, ein Leser oder Schreiber ist, und das Betriebssystem ist völlig ignorant, ob der nächste Thread ein Leser oder Schreiber ist.

Aufgrund dieses Algorithmus verschwindet die Notwendigkeit anzugeben, ob ein Leser oder ein Schreiber bevorzugt wird. Soweit ich weiß, sind die Boost-Bibliotheken jetzt (Boost 1.52) mit diesem fairen Algorithmus implementiert.

Der Terekhov-Algorithmus besteht darin, dass der Lese- / Schreib-Mutex aus zwei Gates besteht: Gate1 und Gate2. Es kann immer nur ein Thread durch jedes Gatter hindurchgehen. Die Gatter können mit einem Mutex und zwei Zustandsvariablen implementiert werden.

Sowohl Leser als auch Autoren versuchen, gate1 zu passieren. Um durch Gate1 zu gehen, muss es wahr sein, dass ein Writer-Thread derzeit nicht innerhalb von Gate1 ist. Wenn dies der Fall ist, versucht der Thread, gate1-Blöcke zu passieren.

Sobald ein Leser-Thread durch Gate1 geht, hat er den Besitz des Mutex gelesen.

Wenn ein Writer-Thread durch gate1 geht, muss er auch durch gate2 gehen, bevor er den Schreibbesitz des Mutex erhält. Es kann nicht durch Gate2 gehen, bis die Anzahl der Leser innerhalb von Gate1 auf Null fällt.

Dies ist ein fairer Algorithmus, denn wenn nur 0 oder mehr Leser innerhalb von gate1 sind, ist es Sache des Betriebssystems, ob der nächste Thread, der in gate1 kommt, ein Leser oder Schreiber ist. Ein Writer wird erst dann "priorisiert", nachdem er durch gate1 gegangen ist, und befindet sich somit als nächstes in der Zeile, um den Besitz des Mutex zu erhalten.

Ich habe Ihr Beispiel für eine Beispielimplementierung verwendet, die schließlich zu shared_timed_mutex in C ++ 14 wurde (mit geringfügigen Änderungen an Ihrem Beispiel). Der folgende Code nennt es shared_mutex , was der Name war, als er vorgeschlagen wurde.

Ich habe die folgenden Ausgaben (alle mit der gleichen ausführbaren Datei):

Manchmal:

%Vor%

Und manchmal:

%Vor%

Und manchmal:

%Vor%

Ich glaube, es sollte theoretisch möglich sein, auch andere Ausgaben zu erhalten, obwohl ich das experimentell nicht bestätigt habe.

Im Interesse der vollständigen Offenlegung, hier ist der genaue Code, den ich ausgeführt habe:

%Vor%     
Howard Hinnant 19.11.2012, 00:06
quelle
1

Eine Google-Suche nach "Boost shared lock hungervation" hat diesen Link angezeigt:

Es sieht so aus, als wäre "upgrade" der Schlüssel. Siehe auch:

paulsm4 22.08.2012 22:47
quelle

Tags und Links