Thread Synchronization: Semaphores and SignalsContentsUnnamed Semaphores Ch14 pp491-501Semaphore OperationsSlide 5ExampleExample – signal safe – shared variableThread with Critical Section (Sem)Slide 9Main programSlide 11Slide 12Semaphore Error CodesA signal is a software notification to a process of an event. Ch8 pp255-283A signal is a software notification to a process of an event.SignalsSlide 17Sending a signalProgramming a signalSlide 20Signal Mask and Signal SetsSignalling and BlockingExample: initialize a signal set:Add SIGINT to the set of blocked signalsCatching and Ignoring Signals: sigactionSet up a signal handler for SIGINTA 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 handlingSummary01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved1Thread Synchronization: Semaphores and SignalsCS 241 Lecture 9(R: Chapter 14 pp 487-501, Ch8 pp255-283, ch13.5 p473-475)Roy Campbell01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved2ContentsPOSIX UnnamedSemaphoresPOSIX Signals (Synchronous)01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved3Unnamed Semaphores Ch14 pp491-501#include <semaphore.h>Sem_t sem;You cannot make a copy of a semaphore POSIX has unnamed and named semaphores.Pshared is 0 in examples meaning only threads of process creating semaphore can use semaphore.#include <semaphore.h>Int sem_init(sem_t *sem, int pshared, unsigned value);01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved4Semaphore OperationsSem_t semA;If (sem_init(&semA, 0, 1) == -1) perror(“Failed to initialize semaphore semA”);#include <semaphore.h>Int sem_destroy(sem_t *sem);•Destroying a semaphore that’s been destroyed gives undefined result. •Destroying a semaphore on which a thread is blocked gives undefined results.01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved5Semaphore Operations#include <semaphore.h>int sem_post(sem_t *sem); /*signal safe*/int sem_trywait(sem_t *sem); /*returns -1 if semaphore is zero – can be interrupted by signal*/int sem_wait(sem_t *sem);/* blocks if semaphore is zero – can be interrupted by signal*/01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved6Example#include <errno.h>#include <semaphore.h>static int shared = 0;static sem_t sharedsem;int initshared(int val) { if (sem_init(&sharedsem, 0, 1) == -1) return -1; shared = val; return 0;}01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved7Example – signal safe – shared variableint getshared(int *sval) { while (sem_wait(&sharedsem) == -1) if (errno != EINTR) return -1; *sval = shared; return sem_post(&sharedsem);}int incshared() { while (sem_wait(&sharedsem) == -1) if (errno != EINTR) return -1; shared++; return sem_post(&sharedsem); }01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved8Thread with Critical Section (Sem)#include <errno.h>#include <pthread.h>#include <semaphore.h>#include <stdio.h>#include <unistd.h>#define TEN_MILLION 10000000L#define BUFSIZE 1024void *threadout(void *args) { char buffer[BUFSIZE]; char *c; sem_t *semlockp; struct timespec sleeptime;01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved9Thread with Critical Section (Sem)/****************** entry section ****************************/ while (sem_wait(semlockp) == -1) /* Entry section */ if(errno != EINTR) { fprintf(stderr, "Thread failed to lock semaphore\n"); return NULL; } /****************** start of critical section *****************/ while (*c != '\0') { fputc(*c, stderr); c++; nanosleep(&sleeptime, NULL); } /****************** exit section ***************************/ if (sem_post(semlockp) == -1) /* Exit section */ fprintf(stderr, "Thread failed to unlock semaphore\n"); /****************** remainder section **********************/ return NULL;}01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved10Main program#include <pthread.h>#include <semaphore.h>#include <stdio.h>#include <stdlib.h>#include <string.h>void *threadout(void *args);int main(int argc, char *argv[]) { int error; int i; int n; sem_t semlock; pthread_t *tids;01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved11Main program if (argc != 2){/* check for valid number of command-line arguments */ fprintf (stderr, "Usage: %s numthreads\n", argv[0]); return 1; } n = atoi(argv[1]); tids = (pthread_t *)calloc(n, sizeof(pthread_t)); if (tids == NULL) { perror("Failed to allocate memory for thread IDs"); return 1; } if (sem_init(&semlock, 0, 1) == -1) { perror("Failed to initialize semaphore"); return 1; }01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved12Main programfor (i = 0; i < n; i++) if (error = pthread_create(tids + i, NULL, threadout, &semlock)) { fprintf(stderr, "Failed to create thread:%s\n", strerror(error)); return 1; } for (i = 0; i < n; i++) if (error = pthread_join(tids[i], NULL)) { fprintf(stderr, "Failed to join thread:%s\n", strerror(error)); return 1; } return 0;}01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved13Semaphore Error CodesEINVAL – value is greater than SEM_VALUE_MAXENOPSC – initialization resource was exhusted, or number of semaphores exceeds SEM_NSEMS_MAXEPERM – caller does not have appropriate privileges01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved14A signal is a software notification to a process of an event. Ch8 pp255-283A signal is generated when the event that causes the signal occurs. A signal is delivered when the process takes action based on the signal. The lifetime of a signal is the interval between its generation and delivery. A signal that has been generated but not yet delivered is pending. A process catches a signal if it executes a signal handler when the signal is delivered. Alternatively, a process can ignore as signal when it is delivered, that is to take no action.01/14/19 CS241 © 2005 Roy Campbell, All Rights Reserved15A signal is a software notification to a process of an event.The function sigaction is used to specify what is to happen to a signal when it is delivered. The signal mask determines the action to be taken when the signal is generated. It contains a list of signals to be blocked. A blocked signal is not delivered to a process until it is unblocked. The function sigprocmask is used to modify the signal mask. Each signal has a default action
View Full Document