Synchronization ProgrammingContentsA correct way to wait for a signalsigwaitSignal Handling and Threads ch13.5 p473-475Directing a signal to a particular threadMasking signals for threadsDedicating threads for signal handlingBounded Buffer Consumer Producer R: Ch 16 pp 549-563Producer Consumer ProblemSlide 11Producer Consumer using SemaphoresProducer Consumer SemaphoresSlide 14Slide 15Classical Problems of Synchronization T:CH 2.4 pp125-132Dining Philosophers (1)Dining Philosophers (2)Dining Philosophers (3)Slide 20Dining Philosophers (4)Slide 22First Readers-Writers ProblemSlide 24The Sleeping Barber Problem (1)The Sleeping Barber Problem (2)Slide 27Slide 28Other Synchronization Primitives T:Ch 2.3 pp 115-124MonitorsMonitor with Condition VariablesSlide 32OptionsDiscussionBarriersSlide 36Message PassingSlide 38Summary01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved1Synchronization ProgrammingCS 241 Lecture 10R: Ch13.5 p473-475, Ch 16 pp549-563, T:Ch 2.4 pp125-132, Ch 2.3 pp 115-124 R: Ch 13.4 pp 465and optionally (R: Ch 13.9 pp 485, Ch 15.4 pp535)Roy Campbell01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved2ContentsPOSIX UnnamedSemaphoresPOSIX Signals (Synchronous)Bounded BuffersClassical Synchronization ProblemsOther Synchronization Primitives01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved3A correct way to wait for a signal 1. static volatile sig_atomic_t sigreceived = 0; 2. 3. sigset_t maskblocked, maskold, maskunblocked; 4. int signum = SIGUSR1; 5. sigprocmask(SIG_SETMASK, NULL, &maskblocked); 6. sigprocmask(SIG_SETMASK, NULL, &maskunblocked); 7. sigaddset(&maskblocked, signum); 8. sigdelset(&maskunblocked, signum); 9. sigprocmask(SIG_BLOCK, &maskblocked, &maskold); 10. while(sigreceived == 0) 11. sigsuspend(&maskunblocked); 12. sigprocmask(SIG_SETMASK, &maskold, NULL); Note. Assume signal handler Sigreceived returns a 1 for signum. Error codes omitted for clarity.01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved4sigwaitBlock all signals Put the signals you want to wait for in a sigset_t call sigwait sigwait blocks the process until at least one of these signals is pending. It removes one of the pending signals and gives you the corresponding signal number in the second parameter.. Do what you want: no signal handler needed. It returns 0 on success and -1 on error with errno set. #include <signal.h> int sigwait(const sigset_t *restrict sigmask, int *restrict signo);01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved5Signal Handling and Threads ch13.5 p473-475type Delivery actionasynchronoussynchronousdirectedDelivered to some thread that it has unblockedDelivered to thread that caused itDelivered to the identified thread01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved6Directing a signal to a particular thread#include <signal.h>#include <pthread.h>int pthread_kill(pthread_t thread, int sig);If successful pthread_kill returns a 0.If (pthread_kill(pthread_self(), SIGKILL)) fprintf(stderr, “failed to commite suicide”\n”);01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved7Masking signals for threads#include <pthread.h>#include <signal.h>int pthread_sigmask(int how, const sigset_t *restrict set, sigset_t *restrict pset);•Each thread has its own signal mask for process wide signals – only use sigprocmask for initialization before creating threads•Can now use signals for thread specific handlers01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved8Dedicating threads for signal handlingDedicate particular threads to handle signalsMain thread blocks all signals before creating any child threadsSignal mask is inherited by childrenThread dedicated to signal handling executes sigwait on specific signals to be handled or uses pthread_sigmask to unblock signal01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved9Bounded Buffer Consumer Producer R: Ch 16 pp 549-563A consumer must not remove an itemThat a producer is busy insertingThat is not thereThat has already been removedA producer must not insert an itemWhen there are no free slotsOverwrite an item that has not been removed01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved10Producer 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;bufinbufout01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved11Producer Consumer Problemint 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);}01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved12Producer Consumer using Semaphoresbufinbufout#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=BUFSIZE01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved13Producer Consumer Semaphoresint 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;}01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved14Producer Consumer Semaphoresint 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; }01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved15Producer Consumer
View Full Document