1 / 35

POSIX Synchronization

Introduction to Operating Systems: Discussion Module 5. POSIX Synchronization. POSIX Synchronization. Synchronization objects are variables in memory that you access just like data.

kyria
Download Presentation

POSIX Synchronization

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Introduction to Operating Systems: Discussion Module 5 POSIX Synchronization

  2. POSIX Synchronization • Synchronization objects are variables in memory that you access just like data. • Threads in different processes can communicate with each other through synchronization objects placed in shared memory. • Threads in different processes are generally invisible to each other. • The available types of synchronization objects include: • Mutex Locks • Condition Variables

  3. Steps in using a mutex • Initialize an attribute object • Reset attribute settings • Can the mutex be shared across processes? • Is there any deadlock protection? • Create a mutex using the attribute object • Use the mutex • Lock, unlock, trylock • Destroy the mutex

  4. Attribute Initialization int pthread_mutexattr_init( pthread_mutexattr_t *mattr); • Use pthread_mutexattr_init() to initialize attributes associated with this object to their default values. Storage for each attribute object is allocated by the threads system during execution. • The default value of the pshared attribute when this function is called is PTHREAD_PROCESS_PRIVATE, which means that the initialized mutex can only be used within a process.

  5. Mutex scope int pthread_mutexattr_setpshared( pthread_mutexattr_t *mattr, intpshared); • The scope of a mutex variable can be either process private (intraprocess) or system wide (interprocess). • If the mutex is created with the pshared attribute set to the PTHREAD_PROCESS_SHAREDstate, and it exists in shared memory, it can be shared among threads from more than one process. • pshared can take one of two values: • PTHREAD_PROCESS_PRIVATE • PTHREAD_PROCESS_SHARED

  6. Mutex Type int pthread_mutexattr_settype( pthread_mutexattr_t *attr , int type); • pthread_mutexattr_settype() sets the mutex type attribute. The type argument specifies the type of mutex. Valid mutex types include: • PTHREAD_MUTEX_NORMAL • This type of mutex does not detect deadlock. • A thread attempting to relock this mutex without first unlocking it will deadlock. • Attempting to unlock a mutex locked by a different thread results in undefined behavior. • Attempting to unlock an unlocked mutex results in undefined behavior.

  7. Mutex Type • PTHREAD_MUTEX_ERRORCHECK • This type of mutex provides error checking. • A thread attempting to relock this mutex without first unlocking it will return with an error. • A thread attempting to unlock a mutex which another thread has locked will return with an error. • A thread attempting to unlock an unlocked mutex will return with an error.

  8. Mutex Type • PTHREAD_MUTEX_RECURSIVE • A thread attempting to relock this mutex without first unlocking it will succeed in locking the mutex. • The relocking deadlock which can occur with mutexes of type PTHREAD_MUTEX_NORMALcannot occur with this type of mutex. • Multiple locks of this mutex require the same number of unlocks to release the mutex before another thread can acquire the mutex. • A thread attempting to unlock a mutex which another thread has locked will return with an error. • A thread attempting to unlock an unlocked mutex will return with an error.

  9. Mutex Type • PTHREAD_MUTEX_DEFAULT • Attempting to recursively lock a mutex of this type results in undefined behavior. • Attempting to unlock a mutex of this type which was not locked by the calling thread results in undefined behavior. • Attempting to unlock a mutex of this type which is not locked results in undefined behavior.

  10. Attribute Destruction int pthread_mutexattr_destroy( pthread_mutexattr_t *mattr); • Before a mutex attribute object can be reinitialized, it must first be destroyed by a call to pthread_mutexattr_destroy(). • If the object is not destroyed, a memory leak will result.

  11. Initialize a Mutex int pthread_mutex_init( pthread_mutex_t*mp, const pthread_mutexattr_t*mattr); • When the mutex is initialized, it is in an unlocked state • A mutex lock must not be reinitialized or destroyed while other threads might be using it. • If a mutex is reinitialized or destroyed, the application must be sure the mutex is not currently in use.

  12. Lock a Mutex int pthread_mutex_lock( pthread_mutex_t*mutex); • Use pthread_mutex_lock() to lock the mutex pointed to by mutex. • When pthread_mutex_lock() returns, the mutex is locked and the calling thread is the owner. • If the mutex is already locked and owned by another thread, the calling thread blocks until the mutex becomes available.

  13. Unlock a Mutex int pthread_mutex_unlock( pthread_mutex_t*mutex); • Use pthread_mutex_unlock() to unlock the mutex pointed to by mutex • pthread_mutex_unlock() releases the mutex object referenced by mutex • If there are threads blocked on the mutex object referenced by mutex when pthread_mutex_unlock()is called, the scheduling policy is used to determine which thread shall acquire the mutex.

  14. Lock with a Nonblocking Mutex int pthread_mutex_trylock( pthread_mutex_t*mutex); • Use pthread_mutex_trylock( ) to attempt to lock the mutex pointed to by mutex • pthread_mutex_trylock()is a non-blocking version of pthread_mutex_lock() • If the mutex object referenced by mutex is currently locked (by any thread, including the current thread), the call returns immediately(EBUSY). Otherwise, the mutex is locked and the calling thread is the owner.

  15. Destroy a Mutex int pthread_mutex_destroy( pthread_mutex_t*mutex); • Use pthread_mutex_destroy( )function to destroy a previously initialized mutex • The mutex can not be used after it has been destroyed • Note that the space for storing the mutex is not freed

  16. mutex.c • #include <pthread.h>#include <unistd.h>static pthread_mutex_t print_lock = PTHREAD_MUTEX_INITIALIZER;static void *print_thread (void *param) { const char *name = param; int i; while (true) { pthread_mutex_lock(& print_lock); printf ("Hello "); printf ("from "); printf ("`%s' ", name); for (i = 'A'; i <= 'Z'; i++) printf ("%c", i); printf ("\r\n"); pthread_mutex_unlock(& print_lock); } return 0;}

  17. mutex.c (continued) int main (void) {pthread_t id;pthread_create (&id, NULL, print_thread, "Thread 1");pthread_create (&id, NULL, print_thread, "Thread 2");pthread_create (&id, NULL, print_thread, "Thread 3");pthread_create (&id, NULL, print_thread, "Thread 4");pthread_create (&id, NULL, print_thread, "Thread 5");pthread_create (&id, NULL, print_thread, "Thread 6");while (1) { pthread_mutex_lock(& print_lock); printf ("sleep\r\n"); pthread_mutex_unlock(& print_lock); sleep (1);}return 0; }

  18. Condition Variables • A condition variable is used to wait until a particular condition is true • like in a monitor • Always use condition variables together with a mutex lock • The mutex provides the mutual exclusive aspect of a monitor • The attributes for condition variables must be set and initialized before the condition variables can be used

  19. Steps in using a condition variable • Create an attribute object • Create a condition variable, associating it with an existing mutex • Use the condition variable • Wait, signal, broadcast • Destroy the condition variable

  20. Attribute Initialization int threads_condattr_init( pthread_condattr_t*cattr); • The pthread_condattr_init()call returns a pointer to an opaque object • The possible values of cattr’s scope are PTHREAD_PROCESS_PRIVATE(the default) and PTHREAD_PROCESS_SHARED • If the object is not destroyed, a memory leak will result

  21. Setting The Scope int pthread_condattr_setpshared( pthread_condattr_t*cattr, intpshared); • pthread_condattr_setpshared( ) sets the scope of a condition variable to either process private(intraprocess) or system wide (interprocess) • PTHREAD_PROCESS_SHARED it can be shared among threads from more than one process • PTHREAD_PROCESS_PRIVATE(default value): only those threads created by the same process can operate on the object

  22. Attribute Destruction int pthread_condattr_destroy( pthread_condattr_t*cattr); • Use pthread_condattr_destroy( ) to remove storage and render the object invalid • The object must be reinitialized before it can be reused

  23. Initialize A Condition Variable int pthread_cond_init( pthread_cond_t*cv, const pthread_condattr_t*cattr); • Initializes the condition variable pointed at by cv to its default value (cattr is NULL), or to specify condition variable attributes that are already set with pthread_condattr_init().

  24. Wait On Condition Variable int pthread_cond_wait( pthread_cond_t*cv, pthread_mutex_t*mp); • Use pthread_cond_wait( ) to release the mutex pointed to by mp and to cause the calling thread to block on the condition variable pointed to by cv • The blocked thread can be awakened by a pthread_cond_signal(), or a pthread_cond_broadcast()

  25. Wait on Condition Variable

  26. Unblock A Thread int pthread_cond_signal( pthread_cond_t*cv); • Use pthread_cond_signal( ) to unblock one thread that is blocked on the condition variable pointed to by cv. • If more than one thread is blocked on a condition variable, the scheduling policy determines the order in which blocked threads are awakened. • For SCHED_OTHER, threads are awakened in priority order.

  27. Condition Signal BEEP

  28. Unblock All Threads Int pthread_cond_broadcast( pthread_cond_t*cv); • Use pthread_cond_broadcast( ) to unblock all threads that are blocked on the condition variable pointed to by cv, specified by pthread_cond_wait(). • When no threads are blocked on the condition variable, pthread_cond_broadcast()has no effect.

  29. Condition Broadcast SQUEAL

  30. Destroy Condition Variable int pthread_cond_destroy( pthread_cond_t*cv); • The pthread_cond_destroy() function destroys a previously initialized condition variable • The condition variable must not be used after it has been destroyed. • The space for storing the condition variable is not freed.

  31. condvar.c #include <pthread.h> #include <stdio.h> #define MAX 1000 #define MAX_COUNT 2000 int count = 0;pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t count_max = PTHREAD_COND_INITIALIZER; int thread_id[3] = {0,1,2}; void increment(void *); void watch(void *);

  32. condvar.c int main(int argc, char *argv[]) { int i; pthread_t thread[3]; pthread_create(&thread[0], NULL, increment, (void*)&thread_id[0]); pthread_create(&thread[1], NULL, increment, (void*)&thread_id[1]); pthread_create(&thread[2], NULL, watch, (void*)&thread_id[2]); for(i=0; i< 3 ; i++) pthread_join(thread[i], NULL); return 0; }

  33. condvar.c (continued) void watch(void* ID) { int* id = (int*)ID; pthread_mutex_lock(&count_mutex); while(count <= MAX_COUNT) { pthread_cond_wait(&count_max, &count_mutex); printf("Inside the watch() and the value is %d\n", count); } pthread_mutex_unlock(&count_mutex); }

  34. condvar.c (continued) void increment(void* ID) { int *id = (int*)ID; int i; for(i=0; i< MAX ; i++) { pthread_mutex_lock(&count_mutex); count++; printf("in increment counter by threadof id :%d, and count :%d\n",*id, count); pthread_cond_signal(&count_max); pthread_mutex_unlock(&count_mutex); } }

  35. Compiling your C++ code with pthreads • You should use the g++ form of complier invocation • You must link with the pthread library • g++ mycode.cpp -lpthread • Use cc or gcc to compile c code • If you don’t include the link option, only your main thread will execute! • This works with Solaris; details vary from system to system.

More Related