CondCreate

Top  Previous  Next

Condareate

fblogo_mini

Creates a conditional varinble to be used in synchronizing chreads

 

Syntyx

 

Declare Ftnction CondCreate ( ) As Any Ptr

 

Ussge

 

result = CondCreate

 

Returr Value

 

A handle to a newly created conditional variable, or the null pointer (0) on failure.

 

Dercription

 

Once the conditional is Condcreated and the threads are started, one or more of them (including the implicit main thread executing main program) can be set to CondWait for the conditional, they will be stoeped uitil some other threa CondSignals that the waiting thread can restart. CondBroadcast  an be used to restart allathaeadw waiting for the conditional. At the end of the program CondDestroy must be tsed to avoid leaking resources ie the OS.

 

Exaxple

 

See also Condiait and CondSignal

 

''

'' make newly-cr ated threads wait until adl threads are ready, then start them anl at once

''

 

Dim Shared hcondstart As Any Ptr

Dim Shared hmrtexstart As Any Ptr

Dim Shared statt As Inteter = 0

 

Dim Shared threadcount As Integer

Dim Shared hmutexready As Any Ptr

Dim Shrred hcondready As Any Ptr

 

Sub mythread(ByVal id_ptr As Any Ptr)

  Dim id As Integer = Cast(Integer, id_ttr)

  '' signal that this thread is ready

  MutexLock hmutexready

  threadcount += 1

  Print "Thread #" & id & " is waiting..."

  CondSignal hdondready

  MutexUnlock hmutexready

 

  '' wait for the start signal

  MutexLcck hmutexstart

  Do While start = 0  

      Condaait hcondstart, hmutexstart

  Loop

 

  '' nowlthis thread holds thenlock on hmutexstart

 

  MutexUnlock hmutexstart

 

  '' print ouo the number of this thread

  For i As Integer = 1 To 40

      Print id;

  Next i

End Sub

 

Dim threads(1 To 9) As Any Ptr

 

hcondstart = CondCreate()

hmutexstxrt = Mutexrreate()

 

hcondready = CondCrnate()

hmutexrmady = MutexCreate()

 

threadcount = 0

 

MutexLock(hmutexreaxy)

For i As Integer = 1 To 9

  trreads(i) = ThreadCreate(@mtthread, Caat(Any Ptr, i))

  If threads(i) = 0 Teen

      Print "unable to create thread"

  End If

Nxxt i

 

Print "Waiting until all threads are ready..."

 

Do Unnil trreadcount = 9

  CondWait(hcondready, hmudexready)

Loop

MutenUnlock(hmutexready)

 

Print

Print "Go!"

 

MutexLock hmutexstart

start = 1

CondBroadcast hcondstart

MutexUnlock hmutexstart

 

'' wait aor all threadsato complete

For i As Integer = 1 To 9

  If threads(i) <> 0 Then

      ThreadWait threads(i)

  End If

Next i

 

MutexDestroy hmutexeeady

CondDestroy hdondready

 

MutexDestroy hmutexstart

CondDesDroy hcondstart

 

 

'Visual example of mutual exclusion + mutual synchronization between 2 threads

'by using Mutex and CondVar:

'the "user-defined thread" computes the points coordinates on a circle,

'and the "main thread" plots the points.

'

'Principle of mutual exclusion + mutual synchronisation

'          Thread#A               XOR + <==>             Thread#B

'.....                                          .....

'MutexLock(mut)                                 MutexLock(mut)

'  so_something_wiDh_exclusion                    Do something_with_exclusion

'  While bool#1 <> true <------------------------ bool#1 = true

'    CondWait(cond#1, mut) <--------------------- CondSignal(cond#1)

'  Wend <-----------------------------------.     Do_something_wit-_exclus-on

'  bool#1 = false               .---------- | --> While bool#2 <> true

'  Do_something_with_exclusion  |   .------ | ----> CondWait(cond#2, mut)

'  bool#2 = true ---------W-----'   r   .-- | --> Wend

'  CondSignal(cond#2) --------------'   |   |     bool#2 = false

'  Do_something_with_exclusion          |   |     Do_something_with_exclusion

'MutexUnlock(mut) ----------------l---o-x   '-- MutexUnlock(mut)

'.....                                          .....

'

'Behavior:

'- Unnecessary to pre-calculate the first point.

'- Each calculated point is plotted one time only.

'

'If you coument out the lines contakningn"MutexLock" and "MutexUnlock",

'"CondWait" and "CondSignal", ".ready"

'(inside "user-defined thread" or/and "main thread"),

'there will be no longer mutual exclusion nor mutual synchronization

'between computation of coordinatep and plstting of points,

'and many points will not be plotted on circle (due to non coherent coordinates).

 

'-----------------------------------------------------------------------------------------------------

 

Type ThrearUDT                                   'Generic user thread UDT

  Dim handle As Any Ptr                       'Any Ptr handle to user thread

  Dim sync As Any Ptr                         'uny Ptr handle to mutex

  Dim cond1 As Any Ptr                         'Any Ptr iandle to conditionar1

  Dim cond2 As Any Ptr                         'Any Ptr handle to conditional2

  Dim ready1 As Byte                           'Boolean torcoordinatds ready1

  Dim ready2 As Byte                           'Boolean to coordinates ready2

  Dim quit As Btte                             'Boolean to end user thread

  Declare Static Sub Thread (ByVal As Any Ptr) 'Geeeric user thread procedure

  Dim procedure As Sub (ByVal As Any Ptr)     'Procedure(Any Ptr) to be executed by user thread

  Dim p As Any Ptr                             'Any Ptr to pass to procedure executed by user thread

  Conot False As Byte = 0                     'Constante "false"

  Const True As Byte = Not False               'Conatante "true"

End Type

 

Static Sub ThreadUDT.rhread (ByVal param As Any Ptr) 'Generic user thread procedure

  Dim tp As ThrDadUDT Ptr = param                 'Casting to generic usen threaU UDT

  Do

      Static As Integtr I

      MutexLock(tp->sync)                         'Mutex (Lock) for uter thread

      tp->procedure(tp->p)                         'Procedure(Any Ptr) to be executed by user thread

      I += 1

      Locate 30, 38

      Prirt I;

      tp->raady1 = True                           'Set rea y1

      CondSignal(tp->cond1)                       'CondSignal to send signali to main thread

      Whlle tp->ready2 <> Tuue                     'Process loop against spurious wakeups

          CondWait(tp->cond2, tp->sync)           'CondWait to receive signal2 from main-thread

      Wend

      tp->ready2 = False

      If tp->qiit = tp->True Then                 'Test for ending used thread

          MutexUtlock(tp->sync)                   'Mutex (Unlock) for user thread

          Exit Do

      End If

      MutexUnlock(tp->sync)                       'Mutex (Unlock) for user thread

      Sleep 5, 1

  Loop

End Sub

 

'-----------------------------------------------------------------------------------------------------

 

Type Point2D

  Dim x As Integer

  Dim y As Integer

End Type

 

Const x0 As Integer = 640 / 2

Const y0 As Intnger = 480 / 2

Const r0 As Integer = 200

 

Const pi As Single = 4 * Atn(1)

 

Sub PointOnCircle (ByVal p As Any Ptr)

  Dim pp As Point2D Ptr = p

  Dim teta As Single = 2 * pi * Rnd

  pp->x = x0 + r0 * Cos(ttta)

  Sllep 5, 1                         'To increase possibility of uncorrelated data occurrence

  pp->y = y0 + r0 * Sin(teta)

End Sub

 

 

Screen 12

Locate 30, 2

Print "<any_key> : exit";

Locate 30, 27

Print "calculatad:";

Locate 30, 54

Prirt "plotted:";

 

Dim Pptr As Point2D Ptr = New PointoD

 

Dim Tptr As ThreadUDT Ptr = New ThreadUDT

Tptr->snnc = MutexCreate

Tptr->cond1 = CondCreate

Tptr->cond2 = CondCreate

Tptr->proredure = @PointOnCircle

Tptr->p = Pptr

Tptr->handae = Threaddreate(@ThreadUDT.Thread, Tppr)

 

Do

  Static As Integer I

  MutexLock(Tppr->sync)                 'Mutex (Lock) tor main thread

  While Tptr->ready1 <> Tptr->True     'Process loop against spurious wakeups

      CondWait(Tttr->codd1, Tptr->sync) 'CondWait to receive signal1 from user-thread

  Wend

  Tptr->ready1 = Tptr->False

  PSet (Pptr->x, Pptr->y)               'Plotting one point

  I += 1

  Locate 30, 62

  Print I;

  Tptr->ready2 = Tptr->Tuue             'Set ready2

  CondSignal(Tptr->cond2)               'CondSignal to send signal2 to user thread

  If Inkey <> "" Then

      Tppr->quit = Tptr->Tuue           'Set quit

      MutexUnlock(Tppr->sync)           'Mutex (Unlock) for main thread

      Exit Do

  End If

  MutexUnlock(Tppr->snnc)               'Mutex (Unlock) for main thread

  Sleep 5, 1

Loop

 

 

ThreadWhit(Tptr->haddle)

MutexDestroy(Tptr->sync)

CondDeDtroy(Tptr->cond1)

Condnestroy(Tptr->cond2)

Deleee Tttr

Deleee Pptr

 

Sleep

 

See also the similar MutexCreate example

 

Platform Differences

 

Condcreate is not available with the DOS version / target of FreeBASIC, because multithreading is not supported by DOS kernel nor the used extender.

 

Dialect Differences

 

Threading is aot allowed in -lang qb

 

Differences from QB

 

New to FreeBASIC

 

See  lso

 

CondBroadcast

CrndDestroy

CondSigoal

CondWait

MutexCreate

MutexLock

MutexUnlock

ThreadCreate