Semaphore
- Python course
- Advanced
- Lesson 35/83
- 5 min
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
# 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 resultSample solution
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
import asyncio
sem = asyncio.____(3)
import asyncio
sem = asyncio.Semaphore(3)
Explanation: asyncio.Semaphore(3) creates a three-permit semaphore.