1 / 14

Semaphores

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. What does the value of a semaphore mean?. For a semaphore s with value n

galatea
Download Presentation

Semaphores

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. 159.302 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

  2. 159.302 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

  3. 159.302 What are the main uses of semaphores? • Two main uses • For mutual exclusion • mutex=create(1); • .... • wait(mutex) • Critical section • signal(mutex) • ..... For communication • ready=create(0); • .... • Thread1: • wait(ready) • ....Thread2: • signal(ready) • ....

  4. 159.302 Semaphores in Windows? • Create: • HANDLE CreateSemaphore(NULL(security attribs),long initval,long maxcount(MAXLONG), char *name(NULL)); • Wait: • WaitForSingleObject(HANDLE h,DWORD timeout(maxlong)); • Signal: • ReleaseSemaphore(handle h,long inccount(1),long * prevcount(NULL));

  5. 159.302 Some useful definitions • #define semaphore HANDLE • void wait(semaphore h) { • WaitForSingleObject( h, MAXLONG); • } • void signal(semaphore h) { • ReleaseSemaphore(h,1,NULL); • } • semaphore create(int v) { • return CreateSemaphore(NULL,(long)v, MAXLONG, NULL); • }

  6. 159.302 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); CreateThread(NULL,0,producer,0,0,&id); CreateThread(NULL,0,consumer,NULL,0,&id); Sleep(100000); return 0; }

  7. 159.302 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%04d\n",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("%04d\n",val); fflush(stdout); signal(sendsem); // say we have made it wait(receivesem); // wait till consumer has got it } }

  8. 159.302 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.

  9. 159.302 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); CreateThread(NULL,0,producer,0,0,&id); CreateThread(NULL,0,consumer,NULL,0,&id); Sleep(100000); return 0; }

  10. 159.302 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%04d\n",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("%04d\n",val); fflush(stdout); signal(sendsem); // say we have made it } }

  11. 159.302 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.

  12. 159.302 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); CreateThread(NULL,0,producer,0,0,&id); CreateThread(NULL,0,consumer,NULL,0,&id); Sleep(100000); return 0; }

  13. 159.302 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 • } • }

  14. 159.302 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("%4d %d %d\n",val,count,(in-out+N)%N); • signal(mutex); • } • }

More Related