Synchronization primitives don't make your code synchronous, they make coroutines in your code synchronized.
Few examples:
- You may want to start/continue some coroutine only when another coroutine allows it (asyncio.Event)
- You may want some part of your code to be executed only by single coroutine at the same time and other to wait for their turn (asyncio.Lock)
- You may want some part of your code to be executed only by limited number on coroutines at the same time (asyncio.Semaphore)
Take a look at a practical example of using asyncio.Semaphore.