Macaulay2 » Documentation
Packages » Macaulay2Doc » The Macaulay2 language » Thing » Mutex
next | previous | forward | backward | up | index | toc

Mutex -- the class of mutexes

Description

A mutex (short for mutual exclusion) is a synchronization primitive used to prevent multiple threads from accessing shared data at the same time. It ensures that only one thread can hold the lock at a time, which helps avoid race conditions in concurrent programs.

In Macaulay2, a Mutex object can be used to protect critical sections of code. When a thread locks a mutex, other threads attempting to lock it will wait until it is unlocked.

For example, suppose multiple threads try to modify the same string. Each thread will need to get the current value of the string, make its modification, and then save the new value. However, there is a good chance that another thread might save its updated value after another thread has fetched it but before it saved the new value. We can see this in the code below.

i1 : msgs = ""

o1 = 
i2 : sayhello = i -> msgs |= "hello from thread #" | toString i | newline

o2 = sayhello

o2 : FunctionClosure
i3 : T = apply(10, i -> schedule(() -> sayhello i))

o3 = {<<task, created>>, <<task, created>>, <<task, created>>, <<task,
     ------------------------------------------------------------------------
     created>>, <<task, created>>, <<task, created>>, <<task, created>>,
     ------------------------------------------------------------------------
     <<task, created>>, <<task, created>>, <<task, created>>}

o3 : List
i4 : while not all(T, isReady) do null
i5 : stack sort lines msgs

o5 = hello from thread #0
     hello from thread #2
     hello from thread #6
     hello from thread #7

We likely ended up with fewer than the expected number of 10 messages. We can get around this issue by using a mutex to lock the string so that only one thread can modify it at a time.

i6 : m = new Mutex

o6 = m

o6 : Mutex
i7 : msgs = ""

o7 = 
i8 : T = apply(10, i -> schedule(() -> (lock m; sayhello i; unlock m)))

o8 = {<<task, created>>, <<task, created>>, <<task, created>>, <<task,
     ------------------------------------------------------------------------
     created>>, <<task, created>>, <<task, created>>, <<task, created>>,
     ------------------------------------------------------------------------
     <<task, created>>, <<task, created>>, <<task, created>>}

o8 : List
i9 : while not all(T, isReady) do null
i10 : stack sort lines msgs

o10 = hello from thread #0
      hello from thread #1
      hello from thread #2
      hello from thread #3
      hello from thread #4
      hello from thread #5
      hello from thread #6
      hello from thread #7
      hello from thread #8
      hello from thread #9

With the mutex, all 10 messages are present.

See also

Menu

Methods that use a mutex:

  • lock(Mutex) -- see lock -- lock a mutex
  • new Mutex -- construct a mutex
  • tryLock(Mutex) -- see tryLock -- try locking a mutex
  • unlock(Mutex) -- see unlock -- unlock a mutex

For the programmer

The object Mutex is a type, with ancestor class Thing.


The source of this document is in /build/reproducible-path/macaulay2-1.26.05+ds/M2/Macaulay2/packages/Macaulay2Doc/doc_mutex.m2:51:0.