05.11.2013 Aufrufe

Zahn - Unix-Netzwerkprogramminerung mit Threads, Sockets und SSL

Zahn - Unix-Netzwerkprogramminerung mit Threads, Sockets und SSL

Zahn - Unix-Netzwerkprogramminerung mit Threads, Sockets und SSL

MEHR ANZEIGEN
WENIGER ANZEIGEN

Erfolgreiche ePaper selbst erstellen

Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.

A.2 Barrieren <strong>mit</strong> POSIX-<strong>Threads</strong> 417<br />

20<br />

22–24<br />

gibt die Anzahl der <strong>Threads</strong> an, die diese Barriere pro Durchlauf erreichen<br />

müssen, bevor die Sperre überw<strong>und</strong>en werden kann. threshold wird dazu<br />

einmalig über barrier_init() initialisiert <strong>und</strong> bleibt danach konstant. Die<br />

counter-Variable gibt Auskunft darüber, wieviele <strong>Threads</strong> die Barriere aktuell<br />

noch erreichen müssen, bevor alle wartenden <strong>Threads</strong> die Barriere wieder<br />

verlassen dürfen. Die Variable cycle stellt schließlich die eigentliche Bedingung<br />

dar, die von den beteiligten <strong>Threads</strong> ausgewertet wird. Wie wir in Beispiel<br />

A.2 noch sehen werden, wird cycle genau dann um eins inkrementiert,<br />

wenn die geforderte Anzahl von <strong>Threads</strong> die Barriere erreicht hat. 9 Die beteiligten<br />

<strong>Threads</strong> verharren also in der Barriere, bis sich der Wert von cycle<br />

verändert hat.<br />

Die Konstante BARRIER_SERIAL_THREAD dient der Auszeichnung eines einzigen,<br />

zufällig ausgewählten <strong>Threads</strong> nach der Rückkehr aus der Funktion<br />

barrier_wait() (siehe unten).<br />

Im Anschluß folgen die Prototypen der drei Funktionen barrier_init(),<br />

barrier_destroy() <strong>und</strong> barrier_wait().<br />

Der barrier_init()-Funktion wird die Adresse einer (noch nicht initialisierten)<br />

barrier_t-Struktur sowie die Anzahl der <strong>mit</strong>tels dieser Barriere zu synchronisierenden<br />

<strong>Threads</strong> übergeben. Die Funktion initialisiert die einzelnen<br />

Komponenten der Datenstruktur (Mutex, Bedingungsvariable, Zähler).<br />

Die Funktion barrier_destroy() verwirft die zuvor <strong>mit</strong>tels barrier_init()<br />

initialisierten Komponenten mutex <strong>und</strong> cv der übergebenen Datenstruktur.<br />

Eine Barriere sollte genau dann entsorgt werden, wenn sie in Zukunft nicht<br />

mehr zur Synchronisation eingesetzt wird.<br />

Die barrier_wait()-Funktion blockiert den aufrufenden Thread so lange,<br />

bis die in der übergebenen barrier_t-Datenstruktur festgelegte Anzahl<br />

von <strong>Threads</strong> die Barriere erreicht hat. Hat die geforderte Anzahl von<br />

<strong>Threads</strong> die referenzierte Barriere erreicht, so kehrt der barrier_wait()-<br />

Aufruf zurück. Ein (zufällig ausgewählter) Thread erhält dabei den Rückgabewert<br />

BARRIER_SERIAL_THREAD, alle anderen <strong>Threads</strong> den Wert 0. Im Fehlerfall<br />

liefert barrier_wait() stattdessen einen der Fehlerursache entsprechenden<br />

Fehlercode zurück.<br />

In Beispiel A.1 ist die Implementierung der drei zuvor beschriebenen Barrieren-<br />

Funktionen barrier_init(), barrier_destroy() <strong>und</strong> barrier_wait() zu<br />

sehen:<br />

9 Zunächst würde man erwarten, daß die auszuwertende Bedingung counter == 0<br />

lautet. Dies erweist sich bei der Implementierung jedoch als unpraktisch, da<br />

der Zähler sofort nach dem Eintreffen des letzten <strong>Threads</strong> (<strong>und</strong> noch bevor der<br />

erste Thread die Barriere verlassen darf) wieder auf den ursprünglichen Wert<br />

threshold gesetzt werden muß. Andernfalls könnte ein Thread die Barriere verlassen<br />

<strong>und</strong> bereits von neuem in die Barriere eintreten, bevor die Barriere für<br />

einen neuen Durchgang vorbereitet wurde.

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!