What’s the problem Process thread1 { Process thread2 { foo = 1; foo = 3; Pthread Synchronization bar = 2; bar = 4; } } Operating Systems •What are the possible results? Hebrew University Spring 2004 Race condition Atomic Updates • Two threads racing to perform the same • Perform the following items as a single unit task • When we are done, exactly (A or B) is true – not (A and B) • Interleaving of operations can cause – not part of A and part of B incorrect behavior • Critical Section! Mutex No problem Process thread1 { Process thread2 { #include <pthread.h> • Enter and Exit critical pthread_mutex_lock(l); pthread_mutex_lock(l); section foo = 1; foo = 3; int pthread_mutex_lock(mutex); bar = 2; bar = 4; pthread_mutex_unlock(l); pthread_mutex_unlock(l); var int pthread_mutex_unlock(mutex); } } access block lock mutex_var •What are the possible results? Thread A Thread B �
What’s the problem? Try it with a mutex Process producer { Process consumer { while(1) { while(1) { while(count == 1) while(count == 0) no_op; no_op; data = c; c = data; count = 1; count = 0; } // consume c } } } One solution Better solution Process producer { Process consumer { Process producer { Process consumer { while(1) { while(1) { while(1) { while(1) { lock(mutex); lock(mutex); // produce c lock(full); if (count == 0){ if (count == 1){ lock(empty); lock(mutex); // produce c c = data; data = c; count = 0; lock(mutex); c = data; count = 1; } data = c; unlock(mutex); } unlock(mutex); unlock(mutex); unlock(empty); unlock(mutex); // consume c unlock(full); // consume c } } } } } } } } •Problems •Produce inside of lock •How many mutexs are in use? •Starvation •What is the initial state of the mutexs? •Busy wait Condition Signals Solution using conditions void producer() { void consumer() { int i = 1; int i = 0; #include <pthread.h> • Wait on a condition while (1) { while (1) { pthread_mutex_t m; pthread_mutex_lock(&mutex); pthread_mutex_lock(&mutex); while (count == 1) { while (count == 0) { pthread_cond_t c; pthread_cond_wait(&control, pthread_cond_wait(&control, • Associated with mutex &mutex); &mutex); } } int pthread_cond_wait(&c, &m) to prevent race data = i; i = data; int pthread_cond_signal(&c); condition count = 1; count = 0; pthread_cond_signal(&control); pthread_cond_signal(&control); int pthread_cond_broadcast(&c); pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex); } } �
Counting Mutex Error Checking Mutex • Linux Extension • Linux Extension: • PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; • PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; • A Partial Semaphore • If called recursively, return an error! • Very helpful for debugging deadlocks • Can be called recursively in a single thread • Counts number of calls and unlocks once count is zero Mutex Maintenance Condition Maintenance • int pthread_mutex_init(&m, &flags) • PTHREAD_COND_INITIALIZER • int pthread_mutex_trylock(&m); • int pthread_cond_init(&c) • int pthread_mutex_destroy(&m); • int pthread_cond_timedwait(&c, &m, &t); • int pthread_cond_destroy(&c) Problems with Solutions Two Phase locking • Barrier • Get all the locks in a consistent order – Wait until all have registered • Do the work • Release the locks in the inverse order – Wait until at least one has registered – Insure that a function is called exactly once • Reduces Deadlocks �
Recommend
More recommend