[NAME] ALL.module.standard.sync [TITLE] Synchronization [DESCRIPTION] Mutex, conditional variable and semaphore are the convetional way for thread synchroniza tion. These constructs synchronize tasklet by block the native threads, so they are not t he recommended way for synchronization and communication channels are the preferrable way . 0.1 Mutex Mutex can be used to synchronize the accessing of shared data structures. It has two stat e: locked and unlocked. A mutex can be locked by only one thread. A thread is suspended w hen it attempt to lock a mutex which has been locked by another thread. 1 mutex = mutex(); Then it can be locked or unlocked by, 1 mutex.lock(); 2 mutex.unlock(); 3 mutex.trylock(); By calling lock(), the calling thread will be block if the mutex is already locked by ano ther thread. If the mutex is locked by the same thread, a second calling of lock() may ca use a deadlock. trylock() is the same as lock() except that it will return immediately in stead of blocking the calling thread if the mutex is already locked. 0.2 Condition Variable Condition variable is a synchronization device which allow a thread to be suspended if a condition is not satisified and resume execution when it is signaled. The basic operation s on a condition is: wait on the condition, or signal the condition. 1 condvar = condition(); Condition variable should always be used together with a mutex. To wait on a condition, 1 mtx.lock() 2 condvar.wait( mtx ); 3 mtx.unlock(); To wait on a condition for a maximum time, 1 mtx.lock() 2 condvar.timedwait( mtx, seconds ); 3 mtx.unlock(); seconds can be a decimal, for example, condvar.timedwait( mtx, 0.005 ) will wait for five miliseconds. 0.3 Semaphore Semaphore can be used to set a limit on resources. It maintains a count for the resource, and allows a thread to proceed, when it attempts to decrease a non-zero count. If the cou nt already reaches 0 before the decrement, the thread will be suspended until the count b ecomes non-zero. When the thread finished using the resource, it should increase the coun t of semaphore. A semaphore must be created with an initial count, 1 sema = semaphore( count ); To access a resource guarded by a semaphore, use, 1 sema.wait() If the resource is acquired, the count of sema will be decreased. To release the resource, use 1 sema.post() which will increase the count. 0.4 State State is an abstraction layer for multiple condition variables coupled with the principle s of atomic operations. Semantically, it represent a state of certain process or object w hich can be set, altered or waited upon by arbitrary number of concurrent tasks. A state contains single value which can be assigned or modified using test-and-set and fetch-and- add principles. One or more threads can wait until a state reaches certain value, in this case the synchronization is similar to using conditional variables with broadcasting. A state can represent an int, float, double, complex or enum value: 1 st = state<int>(0); 2 3 type status = enum<on; off; running; idle; finished; canceled> 4 st2 = state<status>($on + $idle); To perform basic read and write, value() and set() are provided, the latter returns the o ld value of a state: 1 if (st.value() == 0) 2 old = st2.set($off); alter(old, new) can be used to assign new value to a state if it currently contains old v alue. The routine returns non-zero if the operation has succeeded: 1 success = st.alter(0, 1); 2 3 if (success){ 4 ... #will be executed by the only succeeded thread 5 } add() and sub() are meant to add/substract for numeric values and append/remove symbols f or a combined enum. The old value of state is returned: 1 old = st.sub(1); 2 st2.add($finished); To block the current thread until a state is assigned the desired value, wait() is to be used. A timeout may specified, in this case the routine will return zero if time-outed. T o determine what values are currently awaited by other threads, waitlist() is provided: 1 if (2 not in st.waitlist()) 2 success = st.wait(1, 5.0);