Python Threading Locks and Semaphores — ELI5

Imagine you and your roommate share one bathroom. If you both try to walk in at the same time, chaos. So you have a rule: if the door is locked, you wait.

That locked door is a lock in programming.

When your Python program has multiple threads (like multiple workers doing things at the same time), they sometimes need to touch the same piece of data — like a shared bank balance. If Thread A reads the balance ($100), and Thread B also reads it ($100), and they both try to add $50, you might end up with $150 instead of $200. Both thought they were adding to $100.

A lock prevents this. Before touching the shared data, a thread “locks the door.” Any other thread that needs the data has to wait until the door is unlocked. One at a time. No confusion.

Now imagine the bathroom has three stalls. Up to three people can use it at once, but the fourth has to wait. That’s a semaphore — it’s a lock that allows a set number of threads through at the same time. Useful when you want some parallelism but not unlimited access.

The downside? If a thread forgets to unlock the door, everyone waits forever. And if Thread A is waiting for Thread B’s lock while Thread B is waiting for Thread A’s lock, nobody moves. That’s called a deadlock — the programming equivalent of two people blocking a hallway, each waiting for the other to step aside.

One thing to remember: Locks let only one thread in at a time, semaphores let a limited number in — both exist to stop threads from stepping on each other’s work.

pythonconcurrencythreading

See Also

  • Python Actor Model Why treating each piece of your program like a person with their own mailbox makes concurrency way less scary.
  • Python Aiocache Caching aiocache remembers expensive answers so your async Python app doesn't waste time asking the same question twice.
  • Python Aiofiles Async Io aiofiles lets your async Python program read and write files without freezing — because normal file operations secretly block everything.
  • Python Aiohttp Understand Aiohttp through an everyday analogy so Python behavior feels intuitive, not random.
  • Python Anyio Portability AnyIO lets your async Python code work with any async library — write once, run on asyncio or Trio without changes.