Presentation is loading. Please wait.

Presentation is loading. Please wait.

U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science Software Systems Advanced Synchronization Emery Berger and Mark Corner University.

Similar presentations


Presentation on theme: "U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science Software Systems Advanced Synchronization Emery Berger and Mark Corner University."— Presentation transcript:

1 U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science Software Systems Advanced Synchronization Emery Berger and Mark Corner University of Massachusetts Amherst

2 U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science 2 Why Synchronization?  Synchronization serves two purposes: –Ensure safety for shared updates Avoid race conditions –Coordinate actions of threads Parallel computation Event notification  ALL interleavings must be correct –there are lots of interleavings of events –also constrain as little as possible

3 U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science 3 Synch. Operations  Safety: –Locks provide mutual exclusion  Coordination: –Condition variables provide ordering

4 U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science 4 Safety  Multiple threads/processes –access shared resource simultaneously  Safe only if: –All accesses have no effect on resource, e.g., reading a variable, or –All accesses idempotent E.g., a = abs(x), a = highbit(a) –Only one access at a time: mutual exclusion

5 U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science 5 “The too much milk problem” Model of need to synchronize activities Safety: Example

6 U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science 6 thread A if (no milk && no note) leave note buy milk remove note thread B if (no milk && no note) leave note buy milk remove note Does this work? too much milk Why You Need Locks

7 U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science 7 Mutual Exclusion  Prevent more than one thread from accessing critical section –Serializes access to section  Lock, update, unlock: –lock (&l); –update data; /* critical section */ –unlock (&l);

8 U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science 8 thread A lock(&l) if (no milk) buy milk unlock(&l) thread B lock(&l) if (no milk) buy milk unlock(&l) Too Much Milk: Locks

9 U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science What data is shared?  Some data is shared –code, data, heap  Each thread has private data –Stack, SP, PC  All access to shared data must be safe

10 U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science 10 Exercise!  Simple multi-threaded program –N = number of iterations –Spawn that many threads to compute value = expensiveComputation(i) –Add value (safely!) to total  Use: –pthread_mutex_init, _lock, _unlock pthread_mutex_t myLock; –pthread_create, pthread_join pthread_t threads[N];

11 U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science pthread_t theseArethreads[100]; pthread_mutex_t thisIsALock; typedef void * fnType (void *); pthread_create (pthread_t *, NULL, fnType, void *); pthread_join (pthread_t, void *); pthread_mutex_init (pthread_mutex_t *, NULL) pthread_mutex_lock (pthread_mutex_t *) pthread_mutex_unlock (pthread_mutex_t *) 11 Prototypes

12 U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science 12 #include int total = 0; pthread_mutex_t lock; void * wrapper (void * x) { int v = *((int *) x); delete ((int *) x); int res = expComp (v); pthread_mutex_lock (&lock); total += res; pthread_mutex_unlock (&lock); return NULL; } int main (int argc, char * argv[]) { int n = atoi(argv[1]); // mutex init pthread_mutex_init (&lock); // allocate threads pthread_t * threads = new pthread_t[n]; // spawn threads for (int i = 0; i<n; i++) { // heap allocate args int * newI = new int; *newI = i; pthread_create (&threads[i], NULL, wrapper, (void *) newI); } // join for (int i = 0; i<n; i++) { pthread_join (threads[i], NULL); } // done printf (“total = %d\n”, total); return 0; } Solution

13 U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science 13 Synch. Operations  Safety: –Locks provide mutual exclusion  Coordination: –Condition variables provide ordering

14 U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science 14 Synch Problem: Queue  Suppose we have a thread-safe queue –insert(item), remove(), empty() –must protect access with locks  Options for remove when queue empty: –Return special error value (e.g., NULL) –Throw an exception –Wait for something to appear in the queue

15 U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science Three Possible Solutions  Spin –Works?  Could release lock –Works?  Re acquire Lock lock(); while(empty()) {} unlock(); v = remove(); unlock(); while(empty()) {} lock(); v = remove(); lock() while (empty()) { unlock(); lock(); } V = remove(); unlock();

16 U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science Solution: Sleep!  Sleep = –“don’t run me until something happens”  What about this?  Cannot hold lock while sleeping! Dequeue(){ lock(); if (queue empty) { sleep(); } take one item; unlock(); } Enqueue(){ lock(); insert item; if (thread waiting) wake up dequeuer(); unlock(); }

17 U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science Quick Exercise  Does this work? Dequeue(){ lock(); if (queue empty){ unlock(); sleep(); remove item; } else unlock; } Enqueue(){ lock(); insert item; if (thread waiting) wake up dequeuer(); unlock(); }  No! – deq releases lock, then enq looks for sleeping thread

18 U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science Condition Variables  Make it possible/easy to go to sleep –Atomically: release lock put thread on wait queue go to sleep  Each cv has a queue of waiting threads  Worry about threads that have been put on the wait queue but have NOT gone to sleep yet? –no, because those two actions are atomic  Each condition variable associated with one lock

19 U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science 19 Condition Variables  Wait for 1 event, atomically release lock –wait(Lock& l, CV& c) If queue is empty, wait –Atomically releases lock, goes to sleep –You must be holding lock! –May reacquire lock when awakened (pthreads do) –signal(CV& c) Insert item in queue –Wakes up one waiting thread, if any –broadcast(CV& c) Wakes up all waiting threads  Monitors = locks + condition variables –Sometimes combined with data structures

20 U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science Condition Variable Exercise  Implement “Producer Consumer” –One thread enqueues, another dequeues void * consumer (void *){ while (true) { pthread_mutex_lock(&l); while (q.empty()){ pthread_cond_wait(&nempty, &l); } cout << q.pop_back() << endl; pthread_mutex_unlock(&l); }  Two Questions? –Can I use if instead of while (to check cond)? –Can I signal after unlock? void * producer(void *){ while (true) { pthread_mutex_lock(&l); q.push_front (1); pthread_cond_signal(&nempty); pthread_mutex_unlock(&l); }

21 U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science Bounded-Buffer Exercise  Implement “Producer Consumer” –One thread enqueues, another dequeues void * consumer (void *){ while (true) { pthread_mutex_lock(&l); while (q.empty()){ pthread_cond_wait(&nempty, &l); } cout << q.pop_back() << endl; pthread_cond_signal(&nfull); pthread_mutex_unlock(&l); } void * producer(void *){ while (true) { pthread_mutex_lock(&l); while (q.size() == N) { pthread_cond_wait(&nfull,&l); } q.push_front (1); pthread_cond_signal(&nempty); pthread_mutex_unlock(&l); }


Download ppt "U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science Software Systems Advanced Synchronization Emery Berger and Mark Corner University."

Similar presentations


Ads by Google