Sunday, June 18, 2017

Semaphores



Semaphores , can be of 2 types

  1. Couting
  2. Binary

Semaphores which allow an arbitrary resource count are called counting semaphores, while semaphores which are restricted to the values 0 and 1 (or locked/unlocked, unavailable/available) are called binary semaphores.

Library Analogy
Suppose a library has 10 identical study rooms, to be used by one student at a time. To prevent disputes, students must request a room from the front desk if they wish to make use of a study room.

The clerk at the front desk does not keep track of which room is occupied or who is using it, nor does he or she know if the room is actually being used, only the number of free rooms available, which she only knows correctly if all of the students actually use their room and return them when they're done. When a student requests a room, the clerk decreases this number. When a student releases a room, the clerk increases this number. Once access to a room is granted, the room can be used for as long as desired, and so it is not possible to book rooms ahead of time.

In this scenario the front desk represents a semaphore, the rooms are the resources, and the students represent processes. The value of the semaphore in this scenario is initially 10. When a student requests a room he or she is granted access and the value of the semaphore is changed to 9. After the next student comes, it drops to 8, then 7 and so on.

Important observations
When used for a pool of resources, a semaphore tracks only how many resources are free; it does not keep track of which of the resources are free. Some other mechanism (possibly involving more semaphores) may be required to select a particular free resource.

 Let's  see some sample code that represents same


public class LibraryRoomQueue {
 // Semaphore to control the access to the reading room
 private Semaphore semaphore;
 
 // Array to control what room is free
 private boolean freeRooms[];
 
 // Lock to control the access to the freeRooms array
 private Lock lockRooms;
 
 //Constructor of the class. It initializes the three objects
 public LibraryRoomQueue(){
  semaphore=new Semaphore(3);
  freeRooms=new boolean[3];
  for (int i=0; i<3; i++){
   freeRooms[i]=true;
  }
  lockRooms=new ReentrantLock();
 }
 
 public void bookRoom (Object document){
  try {
   // Get access to the semaphore. If there is one or more rooms free,
   // it will get the access to one of the rooms
   semaphore.acquire();
   
   // Get the number of the free room
   int assignedroom=getroom();
   
   Long duration=(long)(Math.random()*10);
   System.out.printf("%s: Booking a room %d during %d seconds\n",Thread.currentThread().getName(),assignedroom,duration);
   TimeUnit.SECONDS.sleep(duration);
   
   // Free the room
   freeRooms[assignedroom]=true;
  } catch (InterruptedException e) {
   e.printStackTrace();
  } finally {
   // Free the semaphore
   semaphore.release();   
  }
 }

 private int getroom() {
  int ret=-1;
  try {
   // Get the access to the array
   lockRooms.lock();
   // Look for the first free room
   for (int i=0; i<freeRooms.length; i++) {
    if (freeRooms[i]){
     ret=i;
     freeRooms[i]=false;
     break;
    }
   }
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   // Free the access to the array
   lockRooms.unlock();
  }
  return ret;
 }

}

:)

No comments: