Semaphores Last Time Semaphores wait n n 1
- Slides: 14
Semaphores Last Time: Semaphores wait(): n = n - 1; if n < 0 then sleep() (atomic until asleep) signal(): n = n + 1; if n <= 0 then wakeup() (all atomic) Today: More on Semaphores 159. 302 1
What does the value of a semaphore mean? For a semaphore s with value n If n is positive then its value is: The number of wakeups that have been performed on s with out sleeps is n If n is negative then its value is: The number of threads sleeping on s is -n 159. 302 2
What are the main uses of semaphores? Two main uses For mutual exclusion For communication mutex=create(1); . . wait(mutex) Critical section signal(mutex). . . ready=create(0); . . Thread 1: wait(ready). . Thread 2: signal(ready). . 159. 302 3
Semaphores in Windows? Create: HANDLE Create. Semaphore(NULL(security attribs), long initval, long maxcount(MAXLONG), char *name(NULL)); Wait: Wait. For. Single. Object(HANDLE h, DWORD timeout(maxlong)); Signal: Release. Semaphore(handle h, long inccount(1), long * prevcount(NULL)); 159. 302 4
Some useful definitions #define semaphore HANDLE void wait(semaphore h) { Wait. For. Single. Object( h, MAXLONG); } void signal(semaphore h) { Release. Semaphore(h, 1, NULL); } semaphore create(int v) { return Create. Semaphore(NULL, (long)v, MAXLONG, NULL); } 159. 302 5
Producer-Consumer int global; // used to hold number being sent semaphore sendsem, receivesem; // for communication int main() { unsigned long id; sendsem=create(0); // initialise to zero receivesem=create(0); Create. Thread(NULL, 0, producer, 0, 0, &id); Create. Thread(NULL, 0, consumer, NULL, 0, &id); Sleep(100000); return 0; } 159. 302 6
Producer-Consumer unsigned long CALLBACK consumer(void *s) { int val; while(1) { wait(sendsem); // wait till producer has made something val=global; // get it signal(receivesem); // say we have got it printf("t%04 dn", val); fflush(stdout); } } unsigned long CALLBACK producer(void *s) { int val; while(1) { val=rand()%1000+1000*(int)s; // make something global=val; // put it somewhere the consumer can see it printf("%04 dn", val); fflush(stdout); signal(sendsem); // say we have made it wait(receivesem); // wait till consumer has got it } } 159. 302 7
Is this OK? This will work for one producer but not for many producers. While the producer is waiting for the consumer it could be producing. Solution: use a lock instead of receivesem A lock is a semaphore initialised to 1 and used to control access to a global variable. 159. 302 8
New Main int global; // used to hold number being sent semaphore sendsem, lock; // for communication int main() { unsigned long id; sendsem=create(0); // initialise to zero lock=create(1); Create. Thread(NULL, 0, producer, 0, 0, &id); Create. Thread(NULL, 0, consumer, NULL, 0, &id); Sleep(100000); return 0; } 159. 302 9
New Producer-Consumer unsigned long CALLBACK consumer(void *s) { int val; while(1) { wait(sendsem); // wait till producer has made something val=global; // get it signal(lock); // release the lock printf("t%04 dn", val); fflush(stdout); } } unsigned long CALLBACK producer(void *s) { int val; while(1) { val=rand()%1000+1000*(int)s; // make something wait(lock); // get the lock global=val; // put val somewhere the consumer can see it printf("%04 dn", val); fflush(stdout); signal(sendsem); // say we have made it } } 159. 302 10
Can we use semaphores for Producer Consumer with a buffer? Yes (also called the bounded buffer problem) use two semaphores thingsinbuffer – initialised to zero spaceinbuffer – initialised to the buffer size The consumer waits on thingsinbuffer and signals spaceinbuffer after it has consumed. The producer waits on spaceinbuffer and signals thingsinbuffer after it has produced. 159. 302 11
Main int buffer[N]; int in=0, out=0; int count=0; semaphore thingsinbuffer, spaceinbuffer, mutex; int main() { unsigned long id; thingsinbuffer=create(0); spaceinbuffer=create(N); mutex=create(1); Create. Thread(NULL, 0, producer, 0, 0, &id); Create. Thread(NULL, 0, consumer, NULL, 0, &id); Sleep(100000); return 0; } 159. 302 12
Producer unsigned long CALLBACK producer(void * s) { int val; } while(1) { val=rand()%1000; Sleep(25); wait(spaceinbuffer); // wait for space in the buffer wait(mutex); buffer[in]=val; in=(in+1)%N; // critical section count=count+1; signal(mutex); signal(thingsinbuffer); // say there are things in the buffer } 159. 302 13
Consumer unsigned long CALLBACK consumer(void * s) { int val; while(1) { wait(thingsinbuffer); // wait till something in buffer wait(mutex); val=buffer[out]; out=(out+1)%N; // critical section count=count-1; signal(mutex); signal(spaceinbuffer); // say there is space in the buffer Sleep(20); wait(mutex); printf("%4 d %d %dn", val, count, (in-out+N)%N); signal(mutex); } } 159. 302 14
- A figure of speech that makes a comparison
- Awr tuning
- Little book of semaphores
- Drawback of semaphore
- Semaphores in os
- Semaphores provide a primitive yet powerful and flexible
- Sleeping barber problem in os
- Types of semaphore
- Semaphore
- Semaphores
- Semaphores and monitors
- Start time, end time and elapsed time
- For the last time sentence
- Did you finish your homework today
- Stalls