CodeBlanks Logo Icon CodeBlanks

Semaphore

Learn concurrency limits with asyncio.Semaphore.

Semaphore

asyncio.Semaphore limits how many coroutines run at once. It generalizes Lock: it allows n coroutines; the rest wait.

sem = asyncio.Semaphore(3)

async with sem:
    # at most 3 coroutines here
    await fetch()

This is useful to avoid overloading an external service. To limit API requests to 3 at a time, use Semaphore(3).

The semaphore value decreases on each acquire and increases on each release. async with does both automatically.

Limiting and resource control

Semaphore is ideal for controlling external resource use. Instead of hundreds of API requests at once, with Semaphore(10) you progress in groups of 10.

This balances speed and quota limits: not too slow, but the service is not overloaded either. The value is found by trial and error; typical values are 5-20.

Lock is effectively Semaphore(1); a single-permit exclusive access.

Practice Limited access with Semaphore

Start with import asyncio. Define sem = asyncio.Semaphore(2). The function async def fetch(n) returns n inside async with sem:. Inside async def main() call await asyncio.gather(fetch(1), fetch(2), fetch(3)) and return it. Add print(asyncio.run(main())).

Starter code

main.py
# import the asyncio module
# define a two-permit semaphore (Semaphore with value 2)
# fetch(n): inside async with sem, return the value n
# main: gather three fetch calls, print result

Sample solution

main.py
import asyncio

sem = asyncio.Semaphore(2)

async def fetch(n):
    async with sem:
        return n

async def main():
    return await asyncio.gather(fetch(1), fetch(2), fetch(3))

print(asyncio.run(main()))

Expected output

[1, 2, 3]

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Match the Semaphore concepts

Term Meaning
Semaphore(3) Three permits
async with sem Acquire and release
acquire Asks permit
release Releases permit

2 What is the relation between Lock and Semaphore(1)?

  • They are completely different
  • Lock is effectively Semaphore(1) Correct answer
  • Semaphore(1) is stronger than Lock
  • Lock equals Semaphore(2)

Explanation: Lock is a single-permit Semaphore; that is, it behaves like Semaphore(1).

3 Define a Semaphore

Question
import asyncio

sem = asyncio.____(3)
Answer
import asyncio

sem = asyncio.Semaphore(3)

Explanation: asyncio.Semaphore(3) creates a three-permit semaphore.

All lessons in Advanced