- A semaphore is a synchronization construct.
- Semaphore provides threads with synchronized access to a limited number of resources.
- A semaphore is just a variable. The variable reflects the number of currently available resources. For example, a parking lot with a display of number of available slots on a specific level of a shopping mall is a semaphore.
- The value of semaphore cannot go less than zero and greater then the total number of the available resources.
- The semaphore is associated with two operations – acquire and release.
- When one of the resources synchronized by a semaphore is "acquired" by a thread, the value of the semaphore is decremented.
- When one of the resources synchronized by a semaphore is "released" by a thread the value of the semaphore is incremented.
- The Dutch computer scientist Edsger Dijkstra invented the concept of semaphore.
- Dijkstra named the two operations on a semaphore acquire and release as p and v using the first letter of the Dutch words proberen and vehogen.
- The word proberen means test and vehogen means increment in Dutch.
Semaphores in Python:
- The Semaphore class of the Python threading module implements the concept of semaphore.
- It has a constructor and two methods acquire() and release().
- The acquire() method decreases the semaphore count if the count is greater than zero. Else it blocks till the count is greater than zero.
- The release() method increases the semaphore count and wakes up one of the threads waiting on the semaphore.
# An example python program using semaphore provided by the python threading module
parkRequests = 0
removeRequests = 0
parked = 0
removed = 0
parkedLock = threading.Lock()
removedLock = threading.Lock()
availbleParkings = threading.Semaphore(10)
parked = parked+1
removed = removed+1
# Thread that simulates the entry of cars into the parking lot
# Creates multiple threads inside to simulate cars that are parked
incomingCar = threading.Thread(target=ParkCar)
parkRequests = parkRequests+1
print("Parking Requests: %d"%(parkRequests))
# Thread that simulates the exit of cars from the parking lot
# Creates multiple threads inside to simulate cars taken out from the parking lot
outgoingCar = threading.Thread(target=RemoveCar)
removeRequests = removeRequests+1
print("Remove Requests: %d"%(removeRequests))
# Start the parking eco-system
parkingEntryThread = threading.Thread(target=parkingEntry)
parkingExitThread = threading.Thread(target=parkingExit)
Parking Requests: 14
Remove Requests: 5
Parking Requests: 15
Parking Requests: 16
Parking Requests: 17
Remove Requests: 6
Parking Requests: 18
Parking Requests: 19
Parking Requests: 20
Remove Requests: 7
Parking Requests: 21
Parking Requests: 22
Parking Requests: 23
Remove Requests: 8
Parking Requests: 24