Buchempfehlung
Windows-Programmierung. Das Entwicklerhandbuch zur WIN32-API
Windows-Programmierung. Das Entwicklerhandbuch zur WIN32-API
"Der" Petzold, das über 1000 Seiten starke Standardwerk zum Win32-API - besonders nützlich u. a. bei der GUI-Programmierung in FreeBASIC! [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

Referenz - CONDCREATE

Referenz-Navigation

 

Syntax: handle = CONDCREATE()
Typ: Funktion
Kategorie: Multithreading

COND steht für "conditional variable". Ebenso wie MUTEXe (siehe BefehlsreferenzeintragMUTEXCREATE) stellen diese eine Möglichkeit dar, Threads (siehe BefehlsreferenzeintragTHREADCREATE) 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 (BefehlsreferenzeintragCONDWAIT), bis ein anderer Thread signalisiert, dass er fortfahren darf (BefehlsreferenzeintragCONDSIGNAL). Wenn alle wartenden Threads auf einmal fortgesetzt werden sollen, kann dies mittels BefehlsreferenzeintragCONDBROADCAST geschehen. Bevor das Programm beendet wird, müssen alle CONDs gelöscht werden, um den Speicherplatz freizugeben (BefehlsreferenzeintragCONDDESTROY).

Der Rückgabetyp ist ein BefehlsreferenzeintragANY 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 BefehlsreferenzeintragMUTEXUNLOCK 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 BefehlsreferenzeintragCONDBROADCAST 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 BefehlsreferenzeintragCONDBROADCAST 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:

Unterschiede unter den FB-Dialektformen:
In der Dialektform Befehlsreferenzeintrag-lang qb steht CONDCREATE nicht zur Verfügung.

Siehe auch:
BefehlsreferenzeintragMultithreading


Zusätzliche Informationen und Funktionen
  • Der Referenzeintrag wurde am 07.07.2007 von RedakteurVolta angelegt.
  • Die aktuellste Version wurde am 01.06.2012 von Redakteurnemored gespeichert.
  Versionen Versionen