 Threads - Maple Programming Help

 Mutex

 Calling Sequence Threads[Mutex][command]( arguments ); command( arguments );

Description

 • The Threads[Mutex] package provides user-level commands for using mutexes in Maple.  Mutexes are used to control access to data when multiple threads are executing.
 • A mutex is an object that can be in one of two states: locked or unlocked. A thread can lock a mutex that is unlocked.  The same thread can later unlock the mutex. When a mutex is locked, any thread attempting to lock the mutex will pause its execution until the mutex is unlocked.  Once the mutex is unlocked, a waiting thread will obtain the lock and continue.
 • If multiple threads are waiting on a locked mutex, and the mutex becomes unlocked, one of the threads will obtain the lock and continue.  Any other threads will continue to wait until they are able to obtain the lock.
 • A typical usage for a mutex is controlling access to a data structure that is shared between multiple threads, for example, two threads processing jobs that are stored in a shared data structure.  Unless the threads protect access to the structure, both threads might attempt to take the same job off the list.  Worst still, the data structure might get corrupted due to the parallel manipulations.
 • To solve this problem using a mutex, associate a mutex with the data structure.  Whenever a thread wants to manipulate the data structure, it must first acquire a lock on the mutex.  Once it has the lock, the thread has exclusive access to the data structure and can manipulate it.  Once the thread is finished with the structure, it unlocks the mutex and processes the job.  If the second thread attempts to access the data structure while the first holds the lock, it will pause and wait for the mutex to become available.

 • The Create command is used to create a new mutex.
 • The Destroy command is used to free the resources associated with the mutex.
 • The Lock command is used to obtain the lock on a mutex.
 • The Unlock command is used to release the lock on a mutex.

Examples

 > p := proc( m )    global count;    print( count );    count := count+1; end proc;
 ${p}{≔}{\mathbf{proc}}\left({m}\right)\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{global}}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{count}}{;}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{print}}{}\left({\mathrm{count}}\right){;}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{count}}{:=}{\mathrm{count}}{+}{1}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{end proc}}$ (1)
 > $\mathrm{count}≔1$
 ${\mathrm{count}}{≔}{1}$ (2)

Create ten threads running the p function.

 > $\mathrm{Threads}\left[\mathrm{Wait}\right]\left(\mathrm{seq}\left(\mathrm{Threads}\left[\mathrm{Create}\right]\left(p\left(m\right)\right),i=1..10\right)\right)$
 ${1}$
 ${2}$
 ${3}$
 ${4}$
 ${5}$
 ${6}$
 ${6}$
 ${8}$
 ${8}$
 ${10}$ (3)

Without mutexes the same value may be printed multiple times.  (You may have to execute this command multiple times to see this occur.)

 > p := proc( m )    global count;    Threads[Mutex][Lock]( m );    print( count );    count := count+1;    Threads[Mutex][Unlock]( m ); end proc;
 ${p}{≔}{\mathbf{proc}}\left({m}\right)\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{global}}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{count}}{;}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{Threads}}{[}{\mathrm{Mutex}}{]}{[}{\mathrm{Lock}}{]}{}\left({m}\right){;}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{print}}{}\left({\mathrm{count}}\right){;}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{count}}{:=}{\mathrm{count}}{+}{1}{;}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{Threads}}{[}{\mathrm{Mutex}}{]}{[}{\mathrm{Unlock}}{]}{}\left({m}\right)\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{end proc}}$ (4)
 > $\mathrm{count}≔1$
 ${\mathrm{count}}{≔}{1}$ (5)
 > $m≔\mathrm{Threads}\left[\mathrm{Mutex}\right]\left[\mathrm{Create}\right]\left(\right)$
 ${m}{≔}{1}$ (6)

Create ten threads running the new p function.

 > $\mathrm{Threads}\left[\mathrm{Wait}\right]\left(\mathrm{seq}\left(\mathrm{Threads}\left[\mathrm{Create}\right]\left(p\left(m\right)\right),i=1..10\right)\right):$
 ${1}$
 ${2}$
 ${3}$
 ${4}$
 ${5}$
 ${6}$
 ${7}$
 ${8}$
 ${9}$
 ${10}$ (7)

Using a mutex allows you to control access to the shared variable.  Thus each number will be printed only once.

 > $\mathrm{Threads}\left[\mathrm{Mutex}\right]\left[\mathrm{Destroy}\right]\left(m\right)$