next up previous contents index
Next: 3.6 Semaphore Up: 3 POSIX threads Previous: 3.4 Beginn und Ende

3.5 Bedingungsvariablen und Mutual exclusion

Zur Implementierung des letzten Sprachkonstrukts

await B then tex2html_wrap_inline2217 end
benötigen wir einige Vorbereitungen.   Zur Verfügung stehen uns die Pthread-Funktionen wait  und signal  mit den folgenden Spezifikationen:
int pthread_cond_wait (pthread_cond_t* cond, pthread_mutex_t* mutex);
Warten auf eine Bedingung bez. eines Mutexes.

int pthread_cond_signal(pthread_cond_t* cond);
Signalisieren einer Bedingung.

int pthread_cond_init (pthread_cond_t* cond, pthread_condattr_t attr);
Initialisieren einer Bedingungsvariablen.

int pthread_cond_broadcast (pthread_cond_t* cond);
Signalisieren einer Bedingung an alle wartenden Pthreads.
     

Die Datentypen pthread_cond_t  und pthread_condattr_t  sowie die Funktionen sind im Header File pthread.h deklariert. Als Attribut kann man ein default-Attribut,  verwenden

       pthread_condattr_t pthread_condattr_default;
das schon initialisiert ist. Nur falls man spezielle Eigenschaften der Bedingungsvariablen haben möchte, muß man sich diese Attribute mit den entsprechenden Funktionen selbst erzeugen. Die Bedingungsvariablen müssen wie Mutexe vor der Benutzung initialisiert werden. Falls die Funktionsaufrufe erfolgreich sind, wird als Error code 0 zurückgegeben, sonst ein Wert < 0.

Eine Variante von wait ist das `timed wait', bei dem eine Zeit mit angegeben wird, wie lange maximal auf das Eintreten einer Bedingung gewartet werden soll.   

Bedingungsvariablen  dienen dazu, den Eintritt bestimmter Bedingungen abzuwarten bzw. die Erfüllung oder den Eintritt einer Bedingung anzuzeigen. Bedingungsvariablen sind an Mutexe  gekoppelt. Beim Warten auf eine Bedingung wird gleichzeitig der lock  auf den gekoppelten Mutex    freigegeben (zuvor muß natürlich ein lock auf diesen Mutex erfolgt sein). Umgekehrt sollte vor dem Signal  auf die Bedingung ein unlock  auf den gekoppelten Mutex erfolgen, damit nach dem wait  auch der lock auf den Mutex wieder vorhanden ist. Ist kein unlock vor dem signal erfolgt, wartet wait wieder bis der lock auf den Mutex möglich ist.

Das Problem bei der Implementierung des await-Statements ist, daß die Bedingung ein beliebiger Boolescher Ausdruck sein darf, wir aber nur eine Boolesche Variable zur Verfügung haben. Die Grundidee bei der Lösung ist zunächst für jede semantisch verschiedene Bedingung eine eigene Bedingungsvariable einzuführen und dann den Test, ob die Bedingung wahr ist an alle (wichtigen) Stellen im Programm zu verlegen, an denen die Bedingung wahr geworden sein könnte und dort, falls ja, mit signal (oder broadcast) den Eintritt der Bedingung zu signalisieren.

Damit ergibt sich das folgende Schema: await B then tex2html_wrap_inline2217 end tex2html_wrap_inline2396

	// globale Variablen:
        pthread_mutex_t globalmux;
        pthread_cont_t  condb;

/* init */    e= pthread_mutex_init (globalmux, pthread_mutexattr_default)
              e= pthread_cond_init (condb, pthread_condattr_default)

/* waiter */  e= pthread_mutex_lock (globalmux);
              while (! B)  e= pthread_cond_wait (condb, globalmux);
              S1; ...; Sn;  
              e= pthread_mutex_unlock(globalmux);

/* tester */  // B koennte wahr werden
              if (B) pthread_cond_signal(condb);
 

Diese Lösung ist allerdings nicht vollständig, da z.B. signal vor wait ausgeführt werden könnte, was den einen Pthread auf immer blockieren würde (sogenannte ``lost signals'').   Eine Lösung zu diesem Problem werden wir im nächsten Abschnitt besprechen.


next up previous contents index
Next: 3.6 Semaphore Up: 3 POSIX threads Previous: 3.4 Beginn und Ende

parallel@rz.uni-mannheim.de
Mon Okt 28 14:38:25 PST 1996