1 / 44

Synchronization Programming

CS 241 Lecture 15 9/29/2006. Synchronization Programming. Yuanyuan Zhou. Chapters: R &R 550-564, Stallings Chapter A.3. Lecture Quiz. Answer bubbles must be carefully shaded in pencil. Put your Last name, Network ID, and student number (UID from student card) in bubble sheet.

ceri
Download Presentation

Synchronization Programming

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. CS 241 Lecture 15 9/29/2006 Synchronization Programming Yuanyuan Zhou Chapters: R &R 550-564, Stallings Chapter A.3

  2. Lecture Quiz • Answer bubbles must be carefully shaded in pencil. • Put your Last name, Network ID, and student number (UID from student card) in bubble sheet. • Turn sheet over and answer each question for the given question numbers • Make sure you submit to the TA

  3. Administrative • This week • MP quiz quizmp3 in Discussion Sections or office hours • SMP4 due Sunday at 10:00pm. • Self Assessment Quiz Wk 6

  4. Content of This Lecture Goals: Having you familiar and comfortable with synchronization programming How? Classic synchronization problems Producer-consumer problem Reader-writer problem Dinning philosopher problem Barber problem Common mistakes

  5. Producer-Consumer Problem • Problem description • A producer: in an infinite loop and produce one item each iteration into the buffer • A consumer: in an infinite loop and consumes one item each iteration from the buffer • Buffer size: can only hold at most N items • Real world example • Web server • Producer: dispatcher threads • Consumer: worker threads

  6. Need 4 volunteers • 1 Consumer • Consume donuts following the program (using step papers) • Each time only one step • 1 Producer • Produce donuts following theprogram ((using step papers) • Each time only one step • 2 Schedulers • Cannot run a process forever • Switch from one to another after 1 or many steps • Try to create some error/deadlock ASAP • Minimize #donuts consumed • Then can eat some donut

  7. Producer-Consumer Program int counter; //initialize to 0 // Producer repeat • read the counter value loud; • if(Counter < 4) { // say it loudly • increment the counter loud; • update the counter with the incremented value; • put a donut onto a plate; //ERROR if no more empty plate}else{ • yield to the scheduler for this turn;} Until YY says stop // consumer repeat • read the counter value loud; • if(Counter > 0) { // say it loudly • decrement counter loud; • update the counter with the incremented value; • consume the donut from a plate; //ERROR if no more donut}else{ • yield to the scheduler for this turn;} Until YY says stop

  8. Producer-Consumer Program int counter; //initialize to 0 Mutex m; // Producer repeat • Mutex_Lock(&m); • read counter value on the board loud; • if(Counter < 4) { // say it loudly • increment the counter loud; • update the counter with the incremented value; • put a donut onto a plate; //ERROR if no more empty plate • Mutex_Unlock(&m)}else{ • yield to the scheduler for this turn;} Until YY says stop // consumer repeat • Mutex_Lock(&m); • read counter value on the board loud; • if(Counter > 0) { // say it loudly • decrement counter loud; • update the counter with the incremented value; • consume the donut from a plate; //ERROR if no more donutMutex_Unlock(&m)}else{ • yield to the scheduler for this turn;} Until YY says stop

  9. Audience: How to fix it? (also donut) int counter; //initialize to 0 Mutex m; // Producer repeat • Mutex_Lock(&m); • read counter value on the board loud; • if(Counter < 4) { // say it loudly • increment the counter loud; • update the counter with the incremented value; • put a donut onto a plate; //ERROR if no more empty plate • Mutex_Unlock(&m);}else{ • yield to the scheduler for this turn;} Until YY says stop // consumer repeat • Mutex_Lock(&m); • read counter value on the board loud; • if(Counter > 0) { // say it loudly • decrement counter loud; • update the counter with the incremented value; • consume the donut from a plate; //ERROR if no more donut • Mutex_Unlock(&m);}else{ • yield to the scheduler for this turn;} Until YY says stop

  10. Correct Implementation: Last Demo int counter; //initialize to 0 Mutex m; // Producer repeat • Mutex_Lock(&m); • read counter value on the board loud; • if(Counter < 4) { // say it loudly • increment the counter loud; • update the counter with the incremented value; • put a donut onto a plate; //ERROR if no more empty plate • Mutex_Unlock(&m);}else{ • Mutex_Unlock(&m); • yield to the scheduler for this turn;} Until YY says stop // consumer repeat • Mutex_Lock(&m); • read counter value on the board loud; • if(Counter > 0) { // say it loudly • decrement counter loud; • update the counter with the incremented value; • consume the donut from a plate; //ERROR if no more donut • Mutex_Unlock(&m);}else{ • Mutex_Unlock(&m); • yield to the scheduler for this turn;} Until YY says stop

  11. A Round of Applause

  12. Another Solution using Semaphores Semaphore Full; //initialize to 0 Semaphore Empty; //initialize to 4 Mutex m; // Producer repeat • P(&empty) • Mutex_lock(&m); • put a donut onto a plate; • Mutex_Unlock(&m); • V(&full); Until YY says stop // consumer repeat • P(&full) • Mutex_lock(&m); • get a donut from a plate; • Mutex_Unlock(&m); • V(&empty); Until YY says stop

  13. First Reader-Writer Problem • readers: read data • writers: write data • Rule: • Multiple readers can read the data simultaneously • Only one writer can write the data at any time • A reader and a writer cannot in critical section together. • Locking table: whether any two can be in the critical section simultaneously

  14. First Reader-Writer Solution • Does it work? What if? • Problem with this solution Mutex m, wrt; int readcount; // shared and initialized to 0 // Writer // Reader Lock(&m); readcount:=readcount+1; Lock(&wrt); if (readcount == 1) lock(&wrt); ...... unlock(&m); writing performed .... ..... reading performed lock(&m); Lock(&wrt); readcount:=readcount-1; if (readcount == 0) unlock(&wrt); Unlock(&m);

  15. Dining Philosophers: an intellectual game • Philosophers eat/think • Eating needs 2 forks • Pick one fork at a time

  16. Need 5 volunteers • 3 Philosophers • Follow the program to • Think • Eat a donut with 2 forks • 2 Schedulers • Cannot run a process forever • Can switch from one to another after 1 or many steps • Try to create some error/deadlock ASAP • Minimize #donuts consumed • Then can eat some donut

  17. Demo 1 Philosopher() { repeat • think; //say something intelligent • take left hand fork; • take right hand fork; • eat one bite; • put left hand fork; • put right hand fork; Until YY says stop; }

  18. Demo 2: Will it work? Mutex m; Philosopher() { repeat • think; //say something intelligent • Mutex_Lock(&m); • take left hand fork; • take right hand fork; • Mutex_Unlock(&m); • eat one bite;Mutex_Lock(&m); • put left hand fork; • put right hand fork; • Mutex_Unlock(&m); Until YY says stop; }

  19. A Round of Applause

  20. Dining Philosophers Solution Please give an implementation of take_forks() and put_forks();

  21. Dining Philosophers Solution

  22. Dining Philosophers Solution

  23. Dining Philosophers Solution

  24. Dining Philosophers Solution

  25. Dining Philosophers Solution

  26. The Sleeping Barber Problem • N customer Chairs • One barber can cut one customer’s hair at any time • No customer, goes to sleep

  27. The Sleeping Barber Solution (1) Please give an implementation of Barber() and Customer();

  28. The Sleeping Barber Solution (2)

  29. The Sleeping Barber Solution (3) Solution to sleeping barber problem.

  30. The Sleeping Barber Solution (2)

  31. Be Careful When Using Semaphores // Violation of Mutual Exclusion Up(mutex); mutexUnlock(); critical section criticalSection(); Down(mutex); mutexLock(); // Deadlock Situation Down(mutex); mutexLock(); critical section criticalSection(); Down(mutex); mutexLock(P); // Violation of Mutual Exclusion (omit wait(mutex)/mutexLock()) critical section critical Section(); Up(mutex); mutexUnlock(); // Deadlock Situation (omit signal(mutex)/mutexUnlock()) Down(mutex); mutexLock(); critical section criticalSection();

  32. Summary Classic synchronization problems Producer-consumer Read-writer Dinning philosopher Sleeping barber

  33. bufin bufout Producer Consumer Problem #include <pthread.h> #include "buffer.h" static buffer_t buffer[BUFSIZE]; static pthread_mutex_t bufferlock = PTHREAD_MUTEX_INITIALIZER; static int bufin = 0; static int bufout = 0;

  34. Producer Consumer Problem int getitem(buffer_t *itemp) { /* remove item from buffer and put in *itemp */ int error; if (error = pthread_mutex_lock(&bufferlock)) /*no mutex, give up*/ return error; *itemp = buffer[bufout]; bufout = (bufout + 1) % BUFSIZE; return pthread_mutex_unlock(&bufferlock); } int putitem(buffer_t item) { /* insert item in the buffer */ int error; if (error = pthread_mutex_lock(&bufferlock)) /*no mutex, give up*/ return error; buffer[bufin] = item; bufin = (bufin + 1) % BUFSIZE; return pthread_mutex_unlock(&bufferlock); }

  35. bufin bufout Producer Consumer using Semaphores #include <errno.h> #include <pthread.h> #include <semaphore.h> #include "buffer.h" static buffer_t buffer[BUFSIZE]; static int bufin = 0; static int bufout = 0; static sem_t mutexbuffer; static sem_t semitems; static sem_t semslots; Note: #semitems+#semslots=BUFSIZE

  36. Producer Consumer Semaphores int bufferinit(void) { /*call this exactly once BEFORE getitem and putitem */ int error; if (sem_init(&semitems, 0, 0)) return errno; if (sem_init(&semslots, 0, BUFSIZE)) { error = errno; sem_destroy(&semitems); /* free the other semaphore */ return error; } if (sem_init(&mutexbuffer, 0, 1)) { error = errno; sem_destroy(&semitems); sem_destroy(&semitems); return error; } return 0; }

  37. Producer Consumer Semaphores int getitem(buffer_t *itemp) { /* remove item from buffer and put in *itemp */ int error; while (((error = sem_wait(&semitems)) == -1) && (errno == EINTR)) ; if (error) return errno; if (error = sem_wait(&mutexbuffer)) return error; *itemp = buffer[bufout]; bufout = (bufout + 1) % BUFSIZE; if (error = sem_post(&mutexbuffer)) return error; if (sem_post(&semslots) == -1) return errno; return 0; }

  38. Producer Consumer Semaphores int putitem(buffer_t item) { /* insert item in the buffer */ int error; while (((error = sem_wait(&semslots)) == -1) && (errno == EINTR)) ; if (error) return errno; if (error = sem_wait(&mutexbuffer)) return error; buffer[bufin] = item; bufin = (bufin + 1) % BUFSIZE; if (error = sem_post(&mutexbuffer)) return error; if (sem_post(&semitems) == -1) return errno; return 0; }

  39. Counter example #include <pthread.h> static int count = 0; static pthread_mutex_t countlock = PTHREAD_MUTEX_INITIALIZER; int increment(void) { /* increment the counter */ int error; if (error = pthread_mutex_lock(&countlock)) return error; count++; return pthread_mutex_unlock(&countlock); }

  40. Counter Example Cont. int decrement(void) { /* decrement the counter */ int error; if (error = pthread_mutex_lock(&countlock)) return error; count--; return pthread_mutex_unlock(&countlock); } int getcount(int *countp) { /* retrieve the counter */ int error; if (error = pthread_mutex_lock(&countlock)) return error; *countp = count; return pthread_mutex_unlock(&countlock); }

  41. Thread safe library calls int randsafe(double *ranp); #include <pthread.h> #include <stdlib.h> int randsafe(double *ranp) { static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; int error; if (error = pthread_mutex_lock(&lock)) return error; *ranp = (rand() + 0.5)/(RAND_MAX + 1.0); return pthread_mutex_unlock(&lock); }

  42. Using a synchronization flag #include <pthread.h> static int doneflag = 0; static pthread_mutex_t donelock = PTHREAD_MUTEX_INITIALIZER; int getdone(int *flag) { /* get the flag */ int error; if (error = pthread_mutex_lock(&donelock)) return error; *flag = doneflag; return pthread_mutex_unlock(&donelock); } int setdone(void) { /* set the flag */ int error; if (error = pthread_mutex_lock(&donelock)) return error; doneflag = 1; return pthread_mutex_unlock(&donelock); }

  43. Thread Safety • Libraries that have static data • Error reports that print on console • Shared data structures like lists

More Related