270 likes | 279 Views
This lecture covers the implementation of producer and consumer processes using mutex and semaphores for synchronization. It also discusses other synchronization primitives such as barriers and message passing. Topics include classical IPC problems like the dining philosophers problem and reader-writer problem.
E N D
CS241 System ProgrammingProcess Synchronization (4) Klara Nahrstedt Lecture 9 2/8/2006
Content • Example: Producer and Consumer Implementation Using Mutex and Semaphores • Other Synchronization Primitives • Barriers • Message Passing • Classical IPC Problems • Dining Philosophers • Reader and Writer • Summary CS 241 - System Programming, Klara Nahrstedt
Administrative • Read: T: Chapter 2.2 and 2.3 • Read: R&R: 16.1-16.3 (Producer and Consumer implementation using mutex and semaphores) • Read: R&R: 13.6 (Readers and Writers) • MP1 is running • Quiz 2: Friday, February 10, 2006 (topic – processes, threads and synchronization) CS 241 - System Programming, Klara Nahrstedt
Bounded Buffer Consumer Producer Implementation Using Mutex and Semaphores(R: Ch 16 pp 549-563) • A consumer must not remove an item • That a producer is busy inserting • That is not there • That has already been removed • A producer must not insert an item • When there are no free slots • Overwrite an item that has not been removed CS 241 - System Programming, Klara Nahrstedt
Producer Consumer Problem bufin bufout #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; CS 241 - System Programming, Klara Nahrstedt
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); } CS 241 - System Programming, Klara Nahrstedt
Producer Consumer using Semaphores bufin bufout #include <errno.h> #include <pthread.h> #include <semaphore.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; static sem_t semitems; static sem_t semslots; Note: #semitems+#semslots=BUFSIZE CS 241 - System Programming, Klara Nahrstedt
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; } return 0; } CS 241 - System Programming, Klara Nahrstedt
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 = pthread_mutex_lock(&bufferlock)) return error; *itemp = buffer[bufout]; bufout = (bufout + 1) % BUFSIZE; if (error = pthread_mutex_unlock(&bufferlock)) return error; if (sem_post(&semslots) == -1) return errno; return 0; } CS 241 - System Programming, Klara Nahrstedt
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 = pthread_mutex_lock(&bufferlock)) return error; buffer[bufin] = item; bufin = (bufin + 1) % BUFSIZE; if (error = pthread_mutex_unlock(&bufferlock)) return error; if (sem_post(&semitems) == -1) return errno; return 0; } CS 241 - System Programming, Klara Nahrstedt
Barriers • Use of a barrier • processes approaching a barrier • all processes but one blocked at barrier • last process arrives, all are let through • Problem: • Waste CPU if workloads are unbalanced CS 241 - System Programming, Klara Nahrstedt
Barriers CS 241 - System Programming, Klara Nahrstedt
Message Passing • Send (destination, &message) • Receive (source, &message) • Message size: Fixed or Variable size. • Real life analogy: conversation CS 241 - System Programming, Klara Nahrstedt
Producer/Consumer Implementation using Message Passing CS 241 - System Programming, Klara Nahrstedt
Indirect Communication send(A,message) /* send a message to mailbox A */ receive(A,message) /* receive a message from mailbox A */ • Mailbox is an abstract object into which a message can be placed to or removed from. CS 241 - System Programming, Klara Nahrstedt
Rendezvous Communication • No buffering – all buffering between sender and receiver is eliminated • Rendezvous Protocol: • If ‘send’ is done before ‘receive’, the sending process blocks until ‘receive happens, and only then a message is copied directly from sender to receiver • If ‘receive’ happens before ‘send’, receiver blocks until ‘send’ happens CS 241 - System Programming, Klara Nahrstedt
Dining Philosophers (1) • Philosophers eat/think • Eating needs 2 forks • Pick one fork at a time • How to prevent deadlock CS 241 - System Programming, Klara Nahrstedt
A nonsolution to the dining philosophers problem Dining Philosophers (2) Does This Work? CS 241 - System Programming, Klara Nahrstedt
binary semaphore s[N]; /* one semaphore per philosopher */ Initialize s[N] to 1 void take_fork(int i) { Down(&s[i]); } void put_fork(int i) {Up(&s[i]); } void philosopher(int i) { while(TRUE) { think(); take_fork(i); take_fork((i+1)%N); eat(); put_fork(i); put_fork((i+1)%N); } } Implementation of Non-solution Problem: Possible Deadlock if each philosopher (in circular manner) takes one fork CS 241 - System Programming, Klara Nahrstedt
To break the deadlock possibility, break the circular waiting, e.g., allow only N-1 philosophers to participate Introduce another counting semaphore for coordination and allow only N-1 philosophers to access the forks semaphore F; /* counting semaphore*/ Initialize F to N-1; void philosopher(int i) { while(TRUE) { think(); down(&F); take_fork(i); take_fork((i+1)%N); eat(); put_fork(i); put_fork((i+1)%N); up(&F); } } Simple Solution to the Deadlock Situation CS 241 - System Programming, Klara Nahrstedt
Dining Philosophers (3) A Solution to dining philosophers problem (part 1) Using Semaphores CS 241 - System Programming, Klara Nahrstedt
Dining Philosophers (3) CS 241 - System Programming, Klara Nahrstedt
Dining Philosophers (4) A Solution to dining philosophers problem (part 2) Using Semaphores CS 241 - System Programming, Klara Nahrstedt
Dining Philosophers (4) CS 241 - System Programming, Klara Nahrstedt
First Readers-Writers Problem • Let processes reading do so concurrently • Let processes writing do so one at a time Typedef in semaphore; Semaphore mutex = 1; Semaphore wrt = 1; Int readc = 0; CS 241 - System Programming, Klara Nahrstedt
Writer While (TRUE) { Think_up_data(); /*noncritical section*/ down(&wrt); do writing up(&wrt); } Reader While (TRUE) { down(&mutex); readc:=readc+1; if readc == 1 then down(&wrt); up(&mutex); do reading down&mutex) readc:=readc-1; if readc == 0 then up(&wrt); up(&mutex); Use read data } First Readers-Writers Problem CS 241 - System Programming, Klara Nahrstedt
Reminder • MP1 due February 13 • Quiz 2 on February 10 CS 241 - System Programming, Klara Nahrstedt