Skip to content
BytePatterns

Semaphores

Concurrency: lesson 9 of 10

Count the permits, not the holders.

Lesson 9 of 10 · 4 min

Semaphores

Step 1 of 10

Three wheelbarrows on a rack. A semaphore counts permits, never who is holding them.

The Idea

A semaphore holds a fixed number of permits. Acquire takes one, release puts one back, and when none are left the next caller waits. It caps how many threads use a limited resource at once — connections, licences, outbound calls.

Real-World Example

An allotment keeps three wheelbarrows on a rack. Take one to your plot, wheel it back when you are done. Nobody schedules anything; the empty rack is the whole message, and the fourth gardener waits by it.

The Code

import threading

barrows = threading.Semaphore(3)     # three permits on the rack

for plot in ["A", "B", "C"]:
    barrows.acquire()
    print(plot, "took a barrow")

print("spare?", barrows.acquire(blocking=False))   # False — rack is empty
barrows.release()                                  # plot A wheels one back
print("spare?", barrows.acquire(blocking=False))   # True

Your turn

Fill in the blank.

import threading

slots = threading.Semaphore(2)
slots.acquire()
slots.acquire()
print(slots.acquire(blocking=False))   # False — both slots busy
___
print(slots.acquire(blocking=False))   # want True

Mini quiz

1 / 3

A semaphore initialised to 1 behaves like: