Linux Modules Character drivers IO & Memory Linux Kernel Process Management Process Address space Linux Scheduler Memory Management Interrupts Signals System Calls Kernel Synchronization Linux Inter Process Communications Serial Ports Parallel Ports Introduction to Hardware Linux Timers DMA in Linux Linux Threads Linux Thread Synchronization Linux Multi Threading Debugging in Linux GDB GNU Debugger KDB Kernel Debugger KGDB Kernel GNU Debugger Example Ethernet Driver |
Synchronization and Critical-sections Multi-threaded programs are concurrent and share the same
process space and can access the same data structures. Threads are scheduled by
OS and are executed at random. When threads are executing (racing to
complete) they may give unexpected results (race condition). Race Condition is a situation in which an unfortunate order of execution causes undesirable behavior. Thread Synchronization The threads library provides three synchronization mechanisms: mutexes: Mutual
exclusion lock: Block access to variables by other threads. This enforces
exclusive access by a thread to a variable or set of variables. joins: Make a thread wait till others are
complete (terminated).
condition variables: data type pthread_cond_t Joins: A join is performed when one wants to wait for a thread to finish. A thread calling routine may launch multiple threads then wait
for them to finish to get the results. One wait for the completion of the threads with a join. int pthread_join( pthreadth, void **thread_return) ; POSIX Mutexes A mutex is a MUTual EXclusion device, and is useful for protecting shared data structures from concurrent modifications, and implementing critical sections and monitors. A mutex has two possible states: unlocked (not owned by any thread), and locked (owned by one thread). #include
< pthread .h > int
pthread_mutex_init ( pthread_mutex_t *mutex, const
pthread_mutex attr_t *mutexattr ) ; int
pthread_mutex_lock ( pthread_mutex_t *mutex ); int
pthread_mutex_unlock (pthread_mutex_t *mutex); int
pthread_mutex_destroy (pthread_mutex_t *mutex); int pthread_trylock ( pthread_mutex_t *mutex ) ; MutexAttributes : int
pthread_mutexattr_init ( pthread_mutexattr_t *attr ) ; int
pthread_mutexattr_destroy( pthread_mutex_t *attr ) ; int
pthread_mutexattr_setkind_np (pthread_mutexattr_t *attr, int kind ) ; int
pthread_mutexattr_getkind_np ( pthread_mutexattr_t *attr , int *kind ) ; Kind can be either PTHREAD_MUTEX_FAST_NP or PTHREAD_MUTEX_RECURSIVE_NP POSIX SEMAPHORES A semaphore is a counter that can be used to synchronize multiple threads. Linux guarantees that checking or modifying the value of a semaphore can be done safely, without creating a race condition. Each semaphore has a counter value, which is a non-negative integer. A semaphore supports two basic operations: A wait operation decrements the value of the semaphore by 1. If the value is already zero, the operation blocks until the value of the semaphore becomes positive. When the semaphore’s value becomes positive, it is decremented by 1 and the wait operation returns. A post operation increments the value of the
semaphore by 1. If the semaphore was previously zero and other threads
are blocked in await operation on that semaphore, one of those threads is
unblocked and its wait operation completes. POSIX
SEMAPHORES #include <semaphore .h> int sem_init( sem_t*sem, intpshared, unsigned intval) ; int sem_wait( sem_t*sem) ; int sem_trywait( sem_t*sem) ; int sem_post( sem_t*sem) ; int sem_getvalue( sem_t*sem, int*sval) ; int sem_destroy( sem_t*sem) ; Condition
Variables A condition variable is a variable of type pthread_cond_t and is used with the appropriate functions for waiting and later, process continuation. The condition variable mechanism allows threads to suspend execution and relinquish the processor until some condition is true A condition variable must always be associated with a mutex to avoid a race condition created by one thread preparing to wait and another thread which may signal the condition before the first thread actually waits on it resulting in a deadlock. Functions used in conjunction with the condition
variable: ü Creating/Destroying: o
pthread_cond_init o
pthread_cond_t
cond = PTHREAD_COND_INITIALIZER; o pthread_cond_destroy ü
Waiting on condition: o
pthread_cond_wait o
pthread_cond_timedwait -place limit on how long it will block. ü
Waking thread based on condition: o
pthread_cond_signal o
pthread_cond_broadcast -wake up all threads blocked by the specified condition variable. Deadlocks
with Two or More Threads Deadlocks can occur when two (or more) threads are each blocked, waiting for a condition to occur that only the other one can cause. For instance, if thread A is blocked on a condition variable waiting for thread B to signal it, and thread B is blocked on a condition variable waiting for thread A to signal it, a deadlock has occurred Because neither thread will ever signal the other. You should take care to avoid the possibility of such situations because they are quite difficult to detect. |