Synchronizing multiple tasks
In this section, we'll take a look at more ways to share data between tasks and synchronize their operations.
Synchronization primitives
The asyncio
package provides lock
, semaphore
, event
, and condition
classes that are pretty similar to the ones we looked at in the context of concurrent.futures
. They provide the same method names and fulfill the same roles. The important difference is that for asyncio's versions, some of the methods are coroutines and some are not, as shown here:

Specifically, in each case, the acquire
and wait
methods, if they exist, are coroutines that must be called by await
.
This is because they need to be able to pause until some specific thing happens, and only a coroutine can pause and hand over control to the scheduler. Having mentioned lock and the rest, I want to point out that while they are sometimes necessary, they are less often needed under asyncio than they would be in concurrent.futures or other systems that provide multiple streams...