xHarbour Reference Documentation > Function Reference |
Creates a Mutex.
HB_MutexCreate() --> pMutexHandle
The function returns a handle to the created Mutex.
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".
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 |
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
http://www.xHarbour.com