Mutexes:
Mutexes have two basic operations, lock and unlock. If a mutex is unlocked and a thread calls lock, the mutex locks and the thread continues. If however the mutex is locked, the thread blocks until the thread 'holding' the lock calls unlock.
There are 5 basic functions dealing with mutexes.
int
pthread_mutex_init (pthread_mutex_t *mut, const pthread_mutexattr_t *attr);
Note that you pass a pointer to the mutex, and that to use the default attributes just pass NULL for the second parameter.
int
pthread_mutex_lock (pthread_mutex_t *mut);
Locks the mutex :).
int
pthread_mutex_unlock (pthread_mutex_t *mut);
Unlocks the mutex :).
int
pthread_mutex_trylock (pthread_mutex_t *mut);
Either acquires the lock if it is available, or returns EBUSY.
int
pthread_mutex_destroy (pthread_mutex_t *mut);
Deallocates any memory or other resources associated with the mutex.
THREAD 1 THREAD 2
pthread_mutex_lock (&mut);
pthread_mutex_lock (&mut);
a = data; /* blocked */
a++; /* blocked */
data = a; /* blocked */
pthread_mutex_unlock (&mut); /* blocked */
b = data;
b--;
data = b;
pthread_mutex_unlock (&mut);
[data is fine. The data race is gone.]
Condition Variables:
To sleep a thread until some condition is satisfied, which other thread will make.
pthread_mutex_lock(&mutex); /* lock mutex */
while (!predicate) { /* check predicate */
pthread_cond_wait(&condvar,&mutex); /* go to sleep - recheck
pred on awakening */
}
pthread_mutex_unlock(&mutex); /* unlock mutex */
when pthread_cond_wait() is called, the mutex is unlocked and the thread goes to sleep waiting for the condition. We need to wake up this thread from another thread
pthread_mutex_lock(&mutex); /* lock the mutex */ predicate=1; /* set the predicate */ pthread_cond_broadcast(&condvar); /* wake everyone up */ pthread_mutex_unlock(&mutex); /* unlock the mutex */
pthread_cond_broadcast() will wake up all the threads waiting for that condition.
When waken up, pthread_cond_wait() will relock the mutex and do further processing.
List of major pthreads routines
- pthread_cancel - cancel running thread
- pthread_create - Creates a thread
- pthread_cond_broadcast - broadcast that the condition variable is changed to all thereads that are waiting
- pthread_cond_destroy - Destroy a condition variable object. The condition variable should be unused, with no threads waiting for it. The memory for the object is left intact; it is up to the caller to deallocate it.
- pthread_cond_init - Initialize a condition variable object, using the provided condition attributes object
- pthread_cond_signal - Wakeup the highest priority thread waiting on a condition variable.Wakes up only one thread
- pthread_cond_wait - The current thread is made to wait until the condition variable is signaled or broadcast. The mutex is released prior to waiting, and reacquired before returning.
- pthread_detach - The thread is detached from its parent ( the one which created it.. Here no need to join later ). If the thread has already exited, its resources are released.
- pthread_exit - The current thread is terminated, with its status value made available to the parent using pthread_join.
- pthread_join - The current thread indicates that it would like to join with the target thread specified by tid. If the target thread has already terminated, its exit status is provided immediately to the caller. If the target thread has not yet exited, the caller is made to wait. Once the target has exited, all of the threads waiting to join with it are woken up, and the target’s exit status provided to each.
- pthread_mutex_destroy - The mutex object is destroyed, although the memory for the object is not deallocated. The mutex must not be held.
- pthread_mutex_init - Initialize the mutex
- pthread_mutex_lock - lock the mutex
- pthread_mutex_unlock - unlock the mutex
- pthread_mutex_trylock - If we call pthread_mutex_trylock on an unlocked mutex, you will lock the mutex as if you had called pthread_mutex_lock, and pthread_mutex_trylock will return zero. However, if the mutex is already locked by another thread, pthread_mutex_trylock will not block. Instead, it will return immediately with the error code EBUSY.The mutex lock held by the other thread is not affected.You may try again later to lock the mutex.
We have 3 kinds of mutexes
fast mutex (by default all mutex are of this type)
recursive mutex
error checking flag mutex
if we call pthread_mutex_lock on a fast mutex two times in the same thread without unlocking, this will cause deadlock.
A recursive mutex maysafely be locked many times by the same thread.The mutex remembers howmany times pthread_mutex_lock was called on it by the thread that holds the lock; that thread must make the same number of calls to pthread_mutex_unlock before the mutex is actually unlocked and another thread is allowed to lock it.
By default, Linux mutexes are fast mutexes. We can modify it by using mutex attributes as shown below
pthread_mutexattr_t attr;
pthread_mutex_t mutex;
pthread_mutexattr_init (&attr);
pthread_mutexattr_setkind_np (&attr, PTHREAD_MUTEX_RECURSIVE_NP
); // we can use PTHREAD_MUTEX_ERRORCHECK_NP for error cheking flags
); // we can use PTHREAD_MUTEX_ERRORCHECK_NP for error cheking flags
pthread_mutex_init (&mutex, &attr);
pthread_mutexattr_destroy (&attr);
No comments:
Post a Comment