Home | History | Annotate | Download | only in library
      1 .. currentmodule:: asyncio
      2 
      3 .. _asyncio-sync:
      4 
      5 ==========================
      6 Synchronization Primitives
      7 ==========================
      8 
      9 asyncio synchronization primitives are designed to be similar to
     10 those of the :mod:`threading` module with two important caveats:
     11 
     12 * asyncio primitives are not thread-safe, therefore they should not
     13   be used for OS thread synchronization (use :mod:`threading` for
     14   that);
     15 
     16 * methods of these synchronization primitives do not accept the *timeout*
     17   argument; use the :func:`asyncio.wait_for` function to perform
     18   operations with timeouts.
     19 
     20 asyncio has the following basic sychronization primitives:
     21 
     22 * :class:`Lock`
     23 * :class:`Event`
     24 * :class:`Condition`
     25 * :class:`Semaphore`
     26 * :class:`BoundedSemaphore`
     27 
     28 
     29 ---------
     30 
     31 
     32 Lock
     33 ====
     34 
     35 .. class:: Lock(\*, loop=None)
     36 
     37    Implements a mutex lock for asyncio tasks.  Not thread-safe.
     38 
     39    An asyncio lock can be used to guarantee exclusive access to a
     40    shared resource.
     41 
     42    The preferred way to use a Lock is an :keyword:`async with`
     43    statement::
     44 
     45        lock = asyncio.Lock()
     46 
     47        # ... later
     48        async with lock:
     49            # access shared state
     50 
     51    which is equivalent to::
     52 
     53        lock = asyncio.Lock()
     54 
     55        # ... later
     56        await lock.acquire()
     57        try:
     58            # access shared state
     59        finally:
     60            lock.release()
     61 
     62    .. coroutinemethod:: acquire()
     63 
     64       Acquire the lock.
     65 
     66       This method waits until the lock is *unlocked*, sets it to
     67       *locked* and returns ``True``.
     68 
     69    .. method:: release()
     70 
     71       Release the lock.
     72 
     73       When the lock is *locked*, reset it to *unlocked* and return.
     74 
     75       If the lock is *unlocked*, a :exc:`RuntimeError` is raised.
     76 
     77    .. method:: locked()
     78 
     79       Return ``True`` if the lock is *locked*.
     80 
     81 
     82 Event
     83 =====
     84 
     85 .. class:: Event(\*, loop=None)
     86 
     87    An event object.  Not thread-safe.
     88 
     89    An asyncio event can be used to notify multiple asyncio tasks
     90    that some event has happened.
     91 
     92    An Event object manages an internal flag that can be set to *true*
     93    with the :meth:`set` method and reset to *false* with the
     94    :meth:`clear` method.  The :meth:`wait` method blocks until the
     95    flag is set to *true*.  The flag is set to *false* initially.
     96 
     97    .. _asyncio_example_sync_event:
     98 
     99    Example::
    100 
    101       async def waiter(event):
    102           print('waiting for it ...')
    103           await event.wait()
    104           print('... got it!')
    105 
    106       async def main():
    107           # Create an Event object.
    108           event = asyncio.Event()
    109 
    110           # Spawn a Task to wait until 'event' is set.
    111           waiter_task = asyncio.create_task(waiter(event))
    112 
    113           # Sleep for 1 second and set the event.
    114           await asyncio.sleep(1)
    115           event.set()
    116 
    117           # Wait until the waiter task is finished.
    118           await waiter_task
    119 
    120       asyncio.run(main())
    121 
    122    .. coroutinemethod:: wait()
    123 
    124       Wait until the event is set.
    125 
    126       If the event is set, return ``True`` immediately.
    127       Otherwise block until another task calls :meth:`set`.
    128 
    129    .. method:: set()
    130 
    131       Set the event.
    132 
    133       All tasks waiting for event to be set will be immediately
    134       awakened.
    135 
    136    .. method:: clear()
    137 
    138       Clear (unset) the event.
    139 
    140       Tasks awaiting on :meth:`wait` will now block until the
    141       :meth:`set` method is called again.
    142 
    143    .. method:: is_set()
    144 
    145       Return ``True`` if the event is set.
    146 
    147 
    148 Condition
    149 =========
    150 
    151 .. class:: Condition(lock=None, \*, loop=None)
    152 
    153    A Condition object.  Not thread-safe.
    154 
    155    An asyncio condition primitive can be used by a task to wait for
    156    some event to happen and then get exclusive access to a shared
    157    resource.
    158 
    159    In essence, a Condition object combines the functionality
    160    of an :class:`Event` and a :class:`Lock`.  It is possible to have
    161    multiple Condition objects share one Lock, which allows coordinating
    162    exclusive access to a shared resource between different tasks
    163    interested in particular states of that shared resource.
    164 
    165    The optional *lock* argument must be a :class:`Lock` object or
    166    ``None``.  In the latter case a new Lock object is created
    167    automatically.
    168 
    169    The preferred way to use a Condition is an :keyword:`async with`
    170    statement::
    171 
    172        cond = asyncio.Condition()
    173 
    174        # ... later
    175        async with cond:
    176            await cond.wait()
    177 
    178    which is equivalent to::
    179 
    180        cond = asyncio.Condition()
    181 
    182        # ... later
    183        await lock.acquire()
    184        try:
    185            await cond.wait()
    186        finally:
    187            lock.release()
    188 
    189    .. coroutinemethod:: acquire()
    190 
    191       Acquire the underlying lock.
    192 
    193       This method waits until the underlying lock is *unlocked*,
    194       sets it to *locked* and returns ``True``.
    195 
    196    .. method:: notify(n=1)
    197 
    198       Wake up at most *n* tasks (1 by default) waiting on this
    199       condition.  The method is no-op if no tasks are waiting.
    200 
    201       The lock must be acquired before this method is called and
    202       released shortly after.  If called with an *unlocked* lock
    203       a :exc:`RuntimeError` error is raised.
    204 
    205    .. method:: locked()
    206 
    207       Return ``True`` if the underlying lock is acquired.
    208 
    209    .. method:: notify_all()
    210 
    211       Wake up all tasks waiting on this condition.
    212 
    213       This method acts like :meth:`notify`, but wakes up all waiting
    214       tasks.
    215 
    216       The lock must be acquired before this method is called and
    217       released shortly after.  If called with an *unlocked* lock
    218       a :exc:`RuntimeError` error is raised.
    219 
    220    .. method:: release()
    221 
    222       Release the underlying lock.
    223 
    224       When invoked on an unlocked lock, a :exc:`RuntimeError` is
    225       raised.
    226 
    227    .. coroutinemethod:: wait()
    228 
    229       Wait until notified.
    230 
    231       If the calling task has not acquired the lock when this method is
    232       called, a :exc:`RuntimeError` is raised.
    233 
    234       This method releases the underlying lock, and then blocks until
    235       it is awakened by a :meth:`notify` or :meth:`notify_all` call.
    236       Once awakened, the Condition re-acquires its lock and this method
    237       returns ``True``.
    238 
    239    .. coroutinemethod:: wait_for(predicate)
    240 
    241       Wait until a predicate becomes *true*.
    242 
    243       The predicate must be a callable which result will be
    244       interpreted as a boolean value.  The final value is the
    245       return value.
    246 
    247 
    248 Semaphore
    249 =========
    250 
    251 .. class:: Semaphore(value=1, \*, loop=None)
    252 
    253    A Semaphore object.  Not thread-safe.
    254 
    255    A semaphore manages an internal counter which is decremented by each
    256    :meth:`acquire` call and incremented by each :meth:`release` call.
    257    The counter can never go below zero; when :meth:`acquire` finds
    258    that it is zero, it blocks, waiting until some task calls
    259    :meth:`release`.
    260 
    261    The optional *value* argument gives the initial value for the
    262    internal counter (``1`` by default). If the given value is
    263    less than ``0`` a :exc:`ValueError` is raised.
    264 
    265    The preferred way to use a Semaphore is an :keyword:`async with`
    266    statement::
    267 
    268        sem = asyncio.Semaphore(10)
    269 
    270        # ... later
    271        async with sem:
    272            # work with shared resource
    273 
    274    which is equivalent to::
    275 
    276        sem = asyncio.Semaphore(10)
    277 
    278        # ... later
    279        await sem.acquire()
    280        try:
    281            # work with shared resource
    282        finally:
    283            sem.release()
    284 
    285    .. coroutinemethod:: acquire()
    286 
    287       Acquire a semaphore.
    288 
    289       If the internal counter is greater than zero, decrement
    290       it by one and return ``True`` immediately.  If it is zero, wait
    291       until a :meth:`release` is called and return ``True``.
    292 
    293    .. method:: locked()
    294 
    295       Returns ``True`` if semaphore can not be acquired immediately.
    296 
    297    .. method:: release()
    298 
    299       Release a semaphore, incrementing the internal counter by one.
    300       Can wake up a task waiting to acquire the semaphore.
    301 
    302       Unlike :class:`BoundedSemaphore`, :class:`Semaphore` allows
    303       making more ``release()`` calls than ``acquire()`` calls.
    304 
    305 
    306 BoundedSemaphore
    307 ================
    308 
    309 .. class:: BoundedSemaphore(value=1, \*, loop=None)
    310 
    311    A bounded semaphore object.  Not thread-safe.
    312 
    313    Bounded Semaphore is a version of :class:`Semaphore` that raises
    314    a :exc:`ValueError` in :meth:`~Semaphore.release` if it
    315    increases the internal counter above the initial *value*.
    316 
    317 
    318 ---------
    319 
    320 
    321 .. deprecated:: 3.7
    322 
    323    Acquiring a lock using ``await lock`` or ``yield from lock`` and/or
    324    :keyword:`with` statement (``with await lock``, ``with (yield from
    325    lock)``) is deprecated.  Use ``async with lock`` instead.
    326