Referenz - CONDCREATE
Syntax: handle = CONDCREATE()
Typ: Funktion
Kategorie: Multithreading
COND steht für "conditional variable". Ebenso wie MUTEXe (siehe MUTEXCREATE) stellen diese eine Möglichkeit dar, Threads (siehe THREADCREATE) zu synchronisieren.
CONDCREATE gibt einen Handle zum COND zurück. Sobald CONDs erstellt und die Threads gestartet wurden, kann ein Thread angewiesen werden, auf ein COND zu warten (CONDWAIT), bis ein anderer Thread signalisiert, dass er fortfahren darf (CONDSIGNAL). Wenn alle wartenden Threads auf einmal fortgesetzt werden sollen, kann dies mittels CONDBROADCAST geschehen. Bevor das Programm beendet wird, müssen alle CONDs gelöscht werden, um den Speicherplatz freizugeben (CONDDESTROY).
Der Rückgabetyp ist ein ANY PTR.
Der Unterschied zwischen MUTEXen und CONDs besteht darin, dass ein MUTEX immer reagiert, sobald er entsperrt wird, während auf ein CONDSIGNAL nur reagiert wird, wenn das entsprechende CONDWAIT gerade ausgeführt wird. Ist der Thread noch mit anderen Anweisungen beschäftigt, geht das CONDSIGNAL verloren. Wird ein MUTEX entsperrt, muss der wartende Thread noch nicht einmal beim entsprechenden Zugriff auf den gerade entsperrten MUTEX angekommen sein, damit das MUTEXUNLOCK seine Wirkung zeigt. Das CONDSIGNAL zeigt seine Wirkung nur dann, wenn der wartende Thread auch wirklich gerade an der Stelle CONDWAIT ist. Es empfiehlt sich daher, vor dem CONDSIGNAL oder CONDBROADCAST ein SLEEP 1 einzubauen, um sicherzustellen, dass die Threads bereit sind, das Signal aufzunehmen.
Beispiel 1:
Dim Shared As Any Ptr hThread1, hThread2, mWait, hCond
Dim Shared As Integer q
Sub Thread (ByVal z As Any Ptr)
Dim As Integer j
MutexLock mWait
Condwait(hCond, mWait)
MutexUnlock mWait
Print *Cast(ZString Ptr, z) & " gestartet"
For j = 0 To 9
MutexLock mWait
Condwait(hCond, mWait)
MutexUnlock mWait
Print *Cast(ZString Ptr, z) & " sendet:"; j
Next
q += 1
End Sub
hCond = Condcreate()
hThread1 = ThreadCreate(@Thread, @"Thread 1")
hThread2 = ThreadCreate(@Thread, @"Thread 2")
mWait = MutexCreate
Print "Beliebige Taste druecken, um Threads zu starten"
Sleep
Condbroadcast(hCond)
Sleep 1
Print
Do
Sleep 1
CondSignal(hCond)
Loop Until q = 2
CondDestroy hCond
ThreadWait(hThread1)
ThreadWait(hThread2)
MutexDestroy mWait
Sleep
Wie man sehen kann, werden die Threads zeitgleich durch das CONDBROADCAST gestartet; das einzelne CONDSIGNAL wird immer abwechselnd an Thread 1 bzw. Thread 2 gesandt.
Beispiel 2:
Dim Shared hcondstart As Any Ptr
Dim Shared hmutexstart As Any Ptr
Dim Shared start As Integer = 0
Dim Shared threadcount As Integer
Dim Shared hmutexready As Any Ptr
Dim Shared hcondready As Any Ptr
Sub mythread(ByVal id_ptr As Any Ptr)
Dim id As Integer = Cast(Integer, id_ptr)
Print "Thread #" & id & " is waiting..."
' Sende Signal, dass dieser Thread bereit ist
MutexLock hmutexready
threadcount += 1
CondSignal hcondready
MutexUnlock hmutexready
' Warte auf das Start-Signal
MutexLock hmutexstart
Do While start = 0
CondWait hcondstart, hmutexstart
Loop
' nun hält dieser Thread den Lock von hmutexstart
MutexUnlock hmutexstart
' Die Nummer dieses Threads ausgeben
For i As Integer = 1 To 40
Print id;
Sleep 1 ' Pause, um andere Threads arbeiten zu lassen
Next i
End Sub
Dim threads(1 To 9) As Any Ptr
' Erstelle die CONDs
hcondstart = CondCreate()
hmutexstart = MutexCreate()
hcondready = CondCreate()
hmutexready = MutexCreate()
threadcount = 0
For i As Integer = 1 To 9
threads(i) = ThreadCreate(@mythread, Cast(Any Ptr, i))
If threads(i) = 0 Then
Print "CONDs konnten nicht erstellt werden!"
End If
Next i
Print "Warte, bis alle Threads bereit sind ..."
MutexLock(hmutexready)
Do Until threadcount = 9
' Warten auf das Signal des Threads, dass er bereit ist
CondWait(hcondready, hmutexready)
Loop
MutexUnlock(hmutexready)
Print "Los!"
' Alle Threads gleichzeitig starten
MutexLock hmutexstart
start = 1
CondBroadcast hcondstart
MutexUnlock hmutexstart
' Warten, bis alle Threads abgeschlossen wurden
For i As Integer = 1 To 9
If threads(i) <> 0 Then
ThreadWait threads(i)
End If
Next i
' Speicher freigeben
MutexDestroy hmutexready
CondDestroy hcondready
MutexDestroy hmutexstart
CondDestroy hcondstart
Sleep
Unterschiede zu QB: neu in FreeBASIC
Plattformbedingte Unterschiede:
In der DOS-Version von FreeBASIC steht CONDCREATE nicht zur Verfügung, da Threads nicht unterstützt werden.
Unterschiede zu früheren Versionen von FreeBASIC:
- CONDCREATE existiert seit FreeBASIC v0.13.
- Seit FreeBASIC v0.17 gibt CONDCREATE einen ANY PTR zurück. Davor war es ein INTEGER.
Unterschiede unter den FB-Dialektformen:
In der Dialektform -lang qb steht CONDCREATE nicht zur Verfügung.
Siehe auch:
Multithreading
Zusätzliche Informationen und Funktionen | ||||
---|---|---|---|---|
|