xHarbour Reference Documentation > Function Reference xHarbour Developers Network  

HB_MutexCreate()

Creates a Mutex.

Syntax

HB_MutexCreate() --> pMutexHandle

Return

The function returns a handle to the created Mutex.

Description

Function HB_MutexCreate() creates a Mutex and returns a handle to it. A Mutex (the name comes from MUTual EXclusion) is a complex data structure required in multi-threaded programming to protect memory resources from concurrent access by multiple threads. There are two distinct programming techniques applied in Mutex usage: Locks and Notifications. No matter which technique is used, a Mutex is only required when at least two threads access the same memory resources or execute the same program code simultaneously. If this is not the case, a Mutex is not required.

Mutex lock

A Mutex can be locked with HB_MutexLock(). The first thread calling this function obtains a lock on the Mutex and can proceed with program execution. Any subsequent thread calling HB_MutexLock() with the same Mutex is suspended by the operating system until the Mutex lock is freed by the locking thread with a call to HB_MutexUnlock().

When the locking thread calls HB_MutexLock() again with the same Mutex, the lock counter is increased and the thread proceeds. HB_MutexUnlock() must then be called as many times as HB_MutexLock() to reset the lock counter to zero for releasing the Mutex lock.

Mutex locking/unlocking is always done in the same thread. A thread holding a lock prevents other threads from executing the same, Mutex protected, program code simultaneously.

Mutex notification

Mutex notifications provide some sort of communication protocol between two threads. This is accomplished by the functions Notify() and Subscribe(). Both functions must operate on the same Mutex but are called in two different threads. If, for example, thread "A" subscribes to a Mutex, it is suspended by the operating system until a second thread "B" notifies the Mutex. When thread "B" calls Notify(), the suspended thread "A" "wakes up" and resumes program execution.

The Subscribe()/Notify() protocol allows for controlling the execution of a thread "A" by a second thread "B".

Info

See also:GetCurrentThread(), GetThreadID(), HB_MutexCreate(), HB_MutexLock(), Notify(), StartThread(), Subscribe()
Category: Multi-threading functions , Mutex functions , xHarbour extensions
Source:vm\thread.c
LIB:xhbmt.lib
DLL:xhbmtdll.dll

Examples

Mutex locking

// The example demonstrates how a routine that is safe for
// single-threaded applications can be made safe for
// a multi-threaded application by means of a Mutex. The two
// routines ShowTIDs_ST() and ShowTIDs_MT() differ only in
// Mutex usage. The output of ShowTIDs_ST() is totally
// scrambled and differs from one program invocation to the
// next when running simultaneously in ten threads. The
// Mutex protected routine ShowTIDs_MT(), in contrast,
// produces always the same, proper output when executed
// by multiple threads.

   GLOBAL pMutex

   PROCEDURE Main
      LOCAL i

      CLS
      ?
      ? "--- Unsafe operation ----"
      FOR i:=1 TO 10
         StartThread( "ShowTIDs_ST" )
      NEXT
      WaitForThreads()

      pMutex := HB_MutexCreate()

      ?
      ? "---- Safe operation -----"
      FOR i:=1 TO 10
         StartThread( "ShowTIDs_MT" )
      NEXT
      WaitForThreads()

   RETURN


   PROCEDURE ShowTIDs_ST()
      LOCAL cTID

      ?  "APP TID:"  , Str( GetThreadID(), 5 )
      ?? "  SYS TID:", Str( GetSystemThreadID(), 5 )
   RETURN


   PROCEDURE ShowTIDs_MT()
      LOCAL cTID

      HB_MutexLock( pMutex )

      ?  "APP TID:"  , Str( GetThreadID(), 5 )
      ?? "  SYS TID:", Str( GetSystemThreadID(), 5 )

      HB_MutexUnlock( pMutex )
   RETURN

 

Mutex notification

// The example demonstrates the technique of Mutex notification.
// Ten threads are started in the FOR...NEXT loop and immediately
// suspended in procedure GetTIDs by subscribing to the Mutex. All
// threads are then notified with NotifyAll() and collect their
// thread IDs in an array which is finally displayed. The result
// of the example is not predictable since the operating system
// schedules the threads for execution on its own behalf.
// I.e. the example produces different output each time it is
// started.
//
// Note that the Mutex is held in a GLOBAL variable to be visible
// when child threads Subscribe() to the Mutex.

   GLOBAL pMutex

   PROCEDURE Main
      LOCAL i, aTID := {}, pThread, aThread := {}

      pMutex := HB_MutexCreate()

      FOR i:=1 TO 10
         pThread := StartThread( "GetTIDs", aTID )
         AAdd( aThread, pThread )
      NEXT

      NotifyAll( pMutex )
      ThreadSleep( 100 )

      AEval( aTID, {|c| QOut(c) } )

   RETURN


   PROCEDURE GetTIDs( aTID )
      LOCAL cTID
      // A thread waits infinitely until notification
      Subscribe( pMutex )

      cTID :=   "APP TID:" + Str( GetThreadID(), 5 )
      cTID += "  SYS TID:" + Str( GetSystemThreadID(), 5 )

      AAdd( aTID, cTID )
   RETURN

Copyright © 2006-2007 xHarbour.com Inc. All rights reserved.
http://www.xHarbour.com
Created by docmaker.exe