Semaphoren: Barrieren-Problem
-
Hi Leute
Befasse mich momentan mit der ganzen Synchronisation von Threads, also vorallem mit 'synchronized', Semaphoren, Mutexes und Lock & Conditions.
Dadurch bin ich auch über einige Beispiele im Internet gestolpert und hab' nun eine Frage bezüglich dem 'Barrieren-Problem'. Beim Problem geht es darum, dass alle n Threads einen bestimmten Punkt im Code erreicht haben müssen, bevor die Threads (oder auch nur einer) weiterfahren kann.Hierzu folgender Pseudo-Code:
// rendezvous an Barriere mutex.wait() count = count + 1 mutex.signal() if count == n: barriere.signal() barriere.wait() barriere.signal() //kritischer Abschnitt
Anmerkung: wait() ist der blockierende Aufruf auf eine Semaphore, die mit 1 initialisiert wurde, d.h. der Wert der Semaphore wird um 1 dekrementiert.
signal() macht das umgekehrte, also um 1 inkrementieren.
barrier ist eine Semaphore, welche mit n (Anzahl Threads) initialisiert wurde.
count ist eine globale Variable zum zählen der Threads, welche bereits an der 'Barriere' angekommen sind.Es wird nun weiterhin erklärt, dass, nachdem alle Threads die Barriere erreicht haben, nur jeweils ein einziger Thread weiterfahren kann, d.h. nur ein Thread kann jeweils im kritischen Abschnitt sein und nach Abschluss kommt der nächste an die Reihe.
Meiner Meinung nach stimmt dies so aber nicht.Nehmen wir an, wir haben 5 Threads. Die ersten 4 Threads müssen warten, weil die if-Abfrage nicht zutrifft und somit keine Freigabe auf der Barriere stattfindet. Hat der 5. Thread den count inkrementiert, kommt er zur if-Abfrage und inkrementiert also auch die Barriere-Semaphore, wobei nun ein Thread, welcher gewartet hat (wait()) weiterfahren kann.
Nachdem besagter Thread weiterfährt, macht er sofort ein signal(), was dazu führt, dass bei einer Thread-Umschaltung ein anderen Thread ebenfalls weiterfahren und in den kritischen Abschnitt gelangen kann.Hab ich da etwas nicht richtig verstanden oder seid ihr auch dieser Meinung?
Hier der Code, wie ich ihn für richtig halte:// rendezvous an Barriere mutex.wait() count = count + 1 mutex.signal() if count == n: barriere.signal() barriere.wait() //kritischer Abschnitt --> kritischer Abschnitt dazwischen! barriere.signal()
Einzige Aenderung wäre hier also, dass der kritische Abschnitt zwischen den beiden wait() und signal() liegt. Somit ist sichergestellt, dass jeweils nur 1 Thread sich im kritischen Abschnitt befindet.
Was ist eure Meinung dazu?
Bin für jede Hilfe und jeden Vorschlag dankbar!Mfg
Rox