17db96d56Sopenharmony_ci.. currentmodule:: asyncio
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ci.. _asyncio-sync:
47db96d56Sopenharmony_ci
57db96d56Sopenharmony_ci==========================
67db96d56Sopenharmony_ciSynchronization Primitives
77db96d56Sopenharmony_ci==========================
87db96d56Sopenharmony_ci
97db96d56Sopenharmony_ci**Source code:** :source:`Lib/asyncio/locks.py`
107db96d56Sopenharmony_ci
117db96d56Sopenharmony_ci-----------------------------------------------
127db96d56Sopenharmony_ci
137db96d56Sopenharmony_ciasyncio synchronization primitives are designed to be similar to
147db96d56Sopenharmony_cithose of the :mod:`threading` module with two important caveats:
157db96d56Sopenharmony_ci
167db96d56Sopenharmony_ci* asyncio primitives are not thread-safe, therefore they should not
177db96d56Sopenharmony_ci  be used for OS thread synchronization (use :mod:`threading` for
187db96d56Sopenharmony_ci  that);
197db96d56Sopenharmony_ci
207db96d56Sopenharmony_ci* methods of these synchronization primitives do not accept the *timeout*
217db96d56Sopenharmony_ci  argument; use the :func:`asyncio.wait_for` function to perform
227db96d56Sopenharmony_ci  operations with timeouts.
237db96d56Sopenharmony_ci
247db96d56Sopenharmony_ciasyncio has the following basic synchronization primitives:
257db96d56Sopenharmony_ci
267db96d56Sopenharmony_ci* :class:`Lock`
277db96d56Sopenharmony_ci* :class:`Event`
287db96d56Sopenharmony_ci* :class:`Condition`
297db96d56Sopenharmony_ci* :class:`Semaphore`
307db96d56Sopenharmony_ci* :class:`BoundedSemaphore`
317db96d56Sopenharmony_ci* :class:`Barrier`
327db96d56Sopenharmony_ci
337db96d56Sopenharmony_ci
347db96d56Sopenharmony_ci---------
357db96d56Sopenharmony_ci
367db96d56Sopenharmony_ci
377db96d56Sopenharmony_ciLock
387db96d56Sopenharmony_ci====
397db96d56Sopenharmony_ci
407db96d56Sopenharmony_ci.. class:: Lock()
417db96d56Sopenharmony_ci
427db96d56Sopenharmony_ci   Implements a mutex lock for asyncio tasks.  Not thread-safe.
437db96d56Sopenharmony_ci
447db96d56Sopenharmony_ci   An asyncio lock can be used to guarantee exclusive access to a
457db96d56Sopenharmony_ci   shared resource.
467db96d56Sopenharmony_ci
477db96d56Sopenharmony_ci   The preferred way to use a Lock is an :keyword:`async with`
487db96d56Sopenharmony_ci   statement::
497db96d56Sopenharmony_ci
507db96d56Sopenharmony_ci       lock = asyncio.Lock()
517db96d56Sopenharmony_ci
527db96d56Sopenharmony_ci       # ... later
537db96d56Sopenharmony_ci       async with lock:
547db96d56Sopenharmony_ci           # access shared state
557db96d56Sopenharmony_ci
567db96d56Sopenharmony_ci   which is equivalent to::
577db96d56Sopenharmony_ci
587db96d56Sopenharmony_ci       lock = asyncio.Lock()
597db96d56Sopenharmony_ci
607db96d56Sopenharmony_ci       # ... later
617db96d56Sopenharmony_ci       await lock.acquire()
627db96d56Sopenharmony_ci       try:
637db96d56Sopenharmony_ci           # access shared state
647db96d56Sopenharmony_ci       finally:
657db96d56Sopenharmony_ci           lock.release()
667db96d56Sopenharmony_ci
677db96d56Sopenharmony_ci   .. versionchanged:: 3.10
687db96d56Sopenharmony_ci      Removed the *loop* parameter.
697db96d56Sopenharmony_ci
707db96d56Sopenharmony_ci   .. coroutinemethod:: acquire()
717db96d56Sopenharmony_ci
727db96d56Sopenharmony_ci      Acquire the lock.
737db96d56Sopenharmony_ci
747db96d56Sopenharmony_ci      This method waits until the lock is *unlocked*, sets it to
757db96d56Sopenharmony_ci      *locked* and returns ``True``.
767db96d56Sopenharmony_ci
777db96d56Sopenharmony_ci      When more than one coroutine is blocked in :meth:`acquire`
787db96d56Sopenharmony_ci      waiting for the lock to be unlocked, only one coroutine
797db96d56Sopenharmony_ci      eventually proceeds.
807db96d56Sopenharmony_ci
817db96d56Sopenharmony_ci      Acquiring a lock is *fair*: the coroutine that proceeds will be
827db96d56Sopenharmony_ci      the first coroutine that started waiting on the lock.
837db96d56Sopenharmony_ci
847db96d56Sopenharmony_ci   .. method:: release()
857db96d56Sopenharmony_ci
867db96d56Sopenharmony_ci      Release the lock.
877db96d56Sopenharmony_ci
887db96d56Sopenharmony_ci      When the lock is *locked*, reset it to *unlocked* and return.
897db96d56Sopenharmony_ci
907db96d56Sopenharmony_ci      If the lock is *unlocked*, a :exc:`RuntimeError` is raised.
917db96d56Sopenharmony_ci
927db96d56Sopenharmony_ci   .. method:: locked()
937db96d56Sopenharmony_ci
947db96d56Sopenharmony_ci      Return ``True`` if the lock is *locked*.
957db96d56Sopenharmony_ci
967db96d56Sopenharmony_ci
977db96d56Sopenharmony_ciEvent
987db96d56Sopenharmony_ci=====
997db96d56Sopenharmony_ci
1007db96d56Sopenharmony_ci.. class:: Event()
1017db96d56Sopenharmony_ci
1027db96d56Sopenharmony_ci   An event object.  Not thread-safe.
1037db96d56Sopenharmony_ci
1047db96d56Sopenharmony_ci   An asyncio event can be used to notify multiple asyncio tasks
1057db96d56Sopenharmony_ci   that some event has happened.
1067db96d56Sopenharmony_ci
1077db96d56Sopenharmony_ci   An Event object manages an internal flag that can be set to *true*
1087db96d56Sopenharmony_ci   with the :meth:`~Event.set` method and reset to *false* with the
1097db96d56Sopenharmony_ci   :meth:`clear` method.  The :meth:`~Event.wait` method blocks until the
1107db96d56Sopenharmony_ci   flag is set to *true*.  The flag is set to *false* initially.
1117db96d56Sopenharmony_ci
1127db96d56Sopenharmony_ci   .. versionchanged:: 3.10
1137db96d56Sopenharmony_ci      Removed the *loop* parameter.
1147db96d56Sopenharmony_ci
1157db96d56Sopenharmony_ci   .. _asyncio_example_sync_event:
1167db96d56Sopenharmony_ci
1177db96d56Sopenharmony_ci   Example::
1187db96d56Sopenharmony_ci
1197db96d56Sopenharmony_ci      async def waiter(event):
1207db96d56Sopenharmony_ci          print('waiting for it ...')
1217db96d56Sopenharmony_ci          await event.wait()
1227db96d56Sopenharmony_ci          print('... got it!')
1237db96d56Sopenharmony_ci
1247db96d56Sopenharmony_ci      async def main():
1257db96d56Sopenharmony_ci          # Create an Event object.
1267db96d56Sopenharmony_ci          event = asyncio.Event()
1277db96d56Sopenharmony_ci
1287db96d56Sopenharmony_ci          # Spawn a Task to wait until 'event' is set.
1297db96d56Sopenharmony_ci          waiter_task = asyncio.create_task(waiter(event))
1307db96d56Sopenharmony_ci
1317db96d56Sopenharmony_ci          # Sleep for 1 second and set the event.
1327db96d56Sopenharmony_ci          await asyncio.sleep(1)
1337db96d56Sopenharmony_ci          event.set()
1347db96d56Sopenharmony_ci
1357db96d56Sopenharmony_ci          # Wait until the waiter task is finished.
1367db96d56Sopenharmony_ci          await waiter_task
1377db96d56Sopenharmony_ci
1387db96d56Sopenharmony_ci      asyncio.run(main())
1397db96d56Sopenharmony_ci
1407db96d56Sopenharmony_ci   .. coroutinemethod:: wait()
1417db96d56Sopenharmony_ci
1427db96d56Sopenharmony_ci      Wait until the event is set.
1437db96d56Sopenharmony_ci
1447db96d56Sopenharmony_ci      If the event is set, return ``True`` immediately.
1457db96d56Sopenharmony_ci      Otherwise block until another task calls :meth:`~Event.set`.
1467db96d56Sopenharmony_ci
1477db96d56Sopenharmony_ci   .. method:: set()
1487db96d56Sopenharmony_ci
1497db96d56Sopenharmony_ci      Set the event.
1507db96d56Sopenharmony_ci
1517db96d56Sopenharmony_ci      All tasks waiting for event to be set will be immediately
1527db96d56Sopenharmony_ci      awakened.
1537db96d56Sopenharmony_ci
1547db96d56Sopenharmony_ci   .. method:: clear()
1557db96d56Sopenharmony_ci
1567db96d56Sopenharmony_ci      Clear (unset) the event.
1577db96d56Sopenharmony_ci
1587db96d56Sopenharmony_ci      Tasks awaiting on :meth:`~Event.wait` will now block until the
1597db96d56Sopenharmony_ci      :meth:`~Event.set` method is called again.
1607db96d56Sopenharmony_ci
1617db96d56Sopenharmony_ci   .. method:: is_set()
1627db96d56Sopenharmony_ci
1637db96d56Sopenharmony_ci      Return ``True`` if the event is set.
1647db96d56Sopenharmony_ci
1657db96d56Sopenharmony_ci
1667db96d56Sopenharmony_ciCondition
1677db96d56Sopenharmony_ci=========
1687db96d56Sopenharmony_ci
1697db96d56Sopenharmony_ci.. class:: Condition(lock=None)
1707db96d56Sopenharmony_ci
1717db96d56Sopenharmony_ci   A Condition object.  Not thread-safe.
1727db96d56Sopenharmony_ci
1737db96d56Sopenharmony_ci   An asyncio condition primitive can be used by a task to wait for
1747db96d56Sopenharmony_ci   some event to happen and then get exclusive access to a shared
1757db96d56Sopenharmony_ci   resource.
1767db96d56Sopenharmony_ci
1777db96d56Sopenharmony_ci   In essence, a Condition object combines the functionality
1787db96d56Sopenharmony_ci   of an :class:`Event` and a :class:`Lock`.  It is possible to have
1797db96d56Sopenharmony_ci   multiple Condition objects share one Lock, which allows coordinating
1807db96d56Sopenharmony_ci   exclusive access to a shared resource between different tasks
1817db96d56Sopenharmony_ci   interested in particular states of that shared resource.
1827db96d56Sopenharmony_ci
1837db96d56Sopenharmony_ci   The optional *lock* argument must be a :class:`Lock` object or
1847db96d56Sopenharmony_ci   ``None``.  In the latter case a new Lock object is created
1857db96d56Sopenharmony_ci   automatically.
1867db96d56Sopenharmony_ci
1877db96d56Sopenharmony_ci   .. versionchanged:: 3.10
1887db96d56Sopenharmony_ci      Removed the *loop* parameter.
1897db96d56Sopenharmony_ci
1907db96d56Sopenharmony_ci   The preferred way to use a Condition is an :keyword:`async with`
1917db96d56Sopenharmony_ci   statement::
1927db96d56Sopenharmony_ci
1937db96d56Sopenharmony_ci       cond = asyncio.Condition()
1947db96d56Sopenharmony_ci
1957db96d56Sopenharmony_ci       # ... later
1967db96d56Sopenharmony_ci       async with cond:
1977db96d56Sopenharmony_ci           await cond.wait()
1987db96d56Sopenharmony_ci
1997db96d56Sopenharmony_ci   which is equivalent to::
2007db96d56Sopenharmony_ci
2017db96d56Sopenharmony_ci       cond = asyncio.Condition()
2027db96d56Sopenharmony_ci
2037db96d56Sopenharmony_ci       # ... later
2047db96d56Sopenharmony_ci       await cond.acquire()
2057db96d56Sopenharmony_ci       try:
2067db96d56Sopenharmony_ci           await cond.wait()
2077db96d56Sopenharmony_ci       finally:
2087db96d56Sopenharmony_ci           cond.release()
2097db96d56Sopenharmony_ci
2107db96d56Sopenharmony_ci   .. coroutinemethod:: acquire()
2117db96d56Sopenharmony_ci
2127db96d56Sopenharmony_ci      Acquire the underlying lock.
2137db96d56Sopenharmony_ci
2147db96d56Sopenharmony_ci      This method waits until the underlying lock is *unlocked*,
2157db96d56Sopenharmony_ci      sets it to *locked* and returns ``True``.
2167db96d56Sopenharmony_ci
2177db96d56Sopenharmony_ci   .. method:: notify(n=1)
2187db96d56Sopenharmony_ci
2197db96d56Sopenharmony_ci      Wake up at most *n* tasks (1 by default) waiting on this
2207db96d56Sopenharmony_ci      condition.  The method is no-op if no tasks are waiting.
2217db96d56Sopenharmony_ci
2227db96d56Sopenharmony_ci      The lock must be acquired before this method is called and
2237db96d56Sopenharmony_ci      released shortly after.  If called with an *unlocked* lock
2247db96d56Sopenharmony_ci      a :exc:`RuntimeError` error is raised.
2257db96d56Sopenharmony_ci
2267db96d56Sopenharmony_ci   .. method:: locked()
2277db96d56Sopenharmony_ci
2287db96d56Sopenharmony_ci      Return ``True`` if the underlying lock is acquired.
2297db96d56Sopenharmony_ci
2307db96d56Sopenharmony_ci   .. method:: notify_all()
2317db96d56Sopenharmony_ci
2327db96d56Sopenharmony_ci      Wake up all tasks waiting on this condition.
2337db96d56Sopenharmony_ci
2347db96d56Sopenharmony_ci      This method acts like :meth:`notify`, but wakes up all waiting
2357db96d56Sopenharmony_ci      tasks.
2367db96d56Sopenharmony_ci
2377db96d56Sopenharmony_ci      The lock must be acquired before this method is called and
2387db96d56Sopenharmony_ci      released shortly after.  If called with an *unlocked* lock
2397db96d56Sopenharmony_ci      a :exc:`RuntimeError` error is raised.
2407db96d56Sopenharmony_ci
2417db96d56Sopenharmony_ci   .. method:: release()
2427db96d56Sopenharmony_ci
2437db96d56Sopenharmony_ci      Release the underlying lock.
2447db96d56Sopenharmony_ci
2457db96d56Sopenharmony_ci      When invoked on an unlocked lock, a :exc:`RuntimeError` is
2467db96d56Sopenharmony_ci      raised.
2477db96d56Sopenharmony_ci
2487db96d56Sopenharmony_ci   .. coroutinemethod:: wait()
2497db96d56Sopenharmony_ci
2507db96d56Sopenharmony_ci      Wait until notified.
2517db96d56Sopenharmony_ci
2527db96d56Sopenharmony_ci      If the calling task has not acquired the lock when this method is
2537db96d56Sopenharmony_ci      called, a :exc:`RuntimeError` is raised.
2547db96d56Sopenharmony_ci
2557db96d56Sopenharmony_ci      This method releases the underlying lock, and then blocks until
2567db96d56Sopenharmony_ci      it is awakened by a :meth:`notify` or :meth:`notify_all` call.
2577db96d56Sopenharmony_ci      Once awakened, the Condition re-acquires its lock and this method
2587db96d56Sopenharmony_ci      returns ``True``.
2597db96d56Sopenharmony_ci
2607db96d56Sopenharmony_ci   .. coroutinemethod:: wait_for(predicate)
2617db96d56Sopenharmony_ci
2627db96d56Sopenharmony_ci      Wait until a predicate becomes *true*.
2637db96d56Sopenharmony_ci
2647db96d56Sopenharmony_ci      The predicate must be a callable which result will be
2657db96d56Sopenharmony_ci      interpreted as a boolean value.  The final value is the
2667db96d56Sopenharmony_ci      return value.
2677db96d56Sopenharmony_ci
2687db96d56Sopenharmony_ci
2697db96d56Sopenharmony_ciSemaphore
2707db96d56Sopenharmony_ci=========
2717db96d56Sopenharmony_ci
2727db96d56Sopenharmony_ci.. class:: Semaphore(value=1)
2737db96d56Sopenharmony_ci
2747db96d56Sopenharmony_ci   A Semaphore object.  Not thread-safe.
2757db96d56Sopenharmony_ci
2767db96d56Sopenharmony_ci   A semaphore manages an internal counter which is decremented by each
2777db96d56Sopenharmony_ci   :meth:`acquire` call and incremented by each :meth:`release` call.
2787db96d56Sopenharmony_ci   The counter can never go below zero; when :meth:`acquire` finds
2797db96d56Sopenharmony_ci   that it is zero, it blocks, waiting until some task calls
2807db96d56Sopenharmony_ci   :meth:`release`.
2817db96d56Sopenharmony_ci
2827db96d56Sopenharmony_ci   The optional *value* argument gives the initial value for the
2837db96d56Sopenharmony_ci   internal counter (``1`` by default). If the given value is
2847db96d56Sopenharmony_ci   less than ``0`` a :exc:`ValueError` is raised.
2857db96d56Sopenharmony_ci
2867db96d56Sopenharmony_ci   .. versionchanged:: 3.10
2877db96d56Sopenharmony_ci      Removed the *loop* parameter.
2887db96d56Sopenharmony_ci
2897db96d56Sopenharmony_ci   The preferred way to use a Semaphore is an :keyword:`async with`
2907db96d56Sopenharmony_ci   statement::
2917db96d56Sopenharmony_ci
2927db96d56Sopenharmony_ci       sem = asyncio.Semaphore(10)
2937db96d56Sopenharmony_ci
2947db96d56Sopenharmony_ci       # ... later
2957db96d56Sopenharmony_ci       async with sem:
2967db96d56Sopenharmony_ci           # work with shared resource
2977db96d56Sopenharmony_ci
2987db96d56Sopenharmony_ci   which is equivalent to::
2997db96d56Sopenharmony_ci
3007db96d56Sopenharmony_ci       sem = asyncio.Semaphore(10)
3017db96d56Sopenharmony_ci
3027db96d56Sopenharmony_ci       # ... later
3037db96d56Sopenharmony_ci       await sem.acquire()
3047db96d56Sopenharmony_ci       try:
3057db96d56Sopenharmony_ci           # work with shared resource
3067db96d56Sopenharmony_ci       finally:
3077db96d56Sopenharmony_ci           sem.release()
3087db96d56Sopenharmony_ci
3097db96d56Sopenharmony_ci   .. coroutinemethod:: acquire()
3107db96d56Sopenharmony_ci
3117db96d56Sopenharmony_ci      Acquire a semaphore.
3127db96d56Sopenharmony_ci
3137db96d56Sopenharmony_ci      If the internal counter is greater than zero, decrement
3147db96d56Sopenharmony_ci      it by one and return ``True`` immediately.  If it is zero, wait
3157db96d56Sopenharmony_ci      until a :meth:`release` is called and return ``True``.
3167db96d56Sopenharmony_ci
3177db96d56Sopenharmony_ci   .. method:: locked()
3187db96d56Sopenharmony_ci
3197db96d56Sopenharmony_ci      Returns ``True`` if semaphore can not be acquired immediately.
3207db96d56Sopenharmony_ci
3217db96d56Sopenharmony_ci   .. method:: release()
3227db96d56Sopenharmony_ci
3237db96d56Sopenharmony_ci      Release a semaphore, incrementing the internal counter by one.
3247db96d56Sopenharmony_ci      Can wake up a task waiting to acquire the semaphore.
3257db96d56Sopenharmony_ci
3267db96d56Sopenharmony_ci      Unlike :class:`BoundedSemaphore`, :class:`Semaphore` allows
3277db96d56Sopenharmony_ci      making more ``release()`` calls than ``acquire()`` calls.
3287db96d56Sopenharmony_ci
3297db96d56Sopenharmony_ci
3307db96d56Sopenharmony_ciBoundedSemaphore
3317db96d56Sopenharmony_ci================
3327db96d56Sopenharmony_ci
3337db96d56Sopenharmony_ci.. class:: BoundedSemaphore(value=1)
3347db96d56Sopenharmony_ci
3357db96d56Sopenharmony_ci   A bounded semaphore object.  Not thread-safe.
3367db96d56Sopenharmony_ci
3377db96d56Sopenharmony_ci   Bounded Semaphore is a version of :class:`Semaphore` that raises
3387db96d56Sopenharmony_ci   a :exc:`ValueError` in :meth:`~Semaphore.release` if it
3397db96d56Sopenharmony_ci   increases the internal counter above the initial *value*.
3407db96d56Sopenharmony_ci
3417db96d56Sopenharmony_ci   .. versionchanged:: 3.10
3427db96d56Sopenharmony_ci      Removed the *loop* parameter.
3437db96d56Sopenharmony_ci
3447db96d56Sopenharmony_ci
3457db96d56Sopenharmony_ciBarrier
3467db96d56Sopenharmony_ci=======
3477db96d56Sopenharmony_ci
3487db96d56Sopenharmony_ci.. class:: Barrier(parties)
3497db96d56Sopenharmony_ci
3507db96d56Sopenharmony_ci   A barrier object.  Not thread-safe.
3517db96d56Sopenharmony_ci
3527db96d56Sopenharmony_ci   A barrier is a simple synchronization primitive that allows to block until
3537db96d56Sopenharmony_ci   *parties* number of tasks are waiting on it.
3547db96d56Sopenharmony_ci   Tasks can wait on the :meth:`~Barrier.wait` method and would be blocked until
3557db96d56Sopenharmony_ci   the specified number of tasks end up waiting on :meth:`~Barrier.wait`.
3567db96d56Sopenharmony_ci   At that point all of the waiting tasks would unblock simultaneously.
3577db96d56Sopenharmony_ci
3587db96d56Sopenharmony_ci   :keyword:`async with` can be used as an alternative to awaiting on
3597db96d56Sopenharmony_ci   :meth:`~Barrier.wait`.
3607db96d56Sopenharmony_ci
3617db96d56Sopenharmony_ci   The barrier can be reused any number of times.
3627db96d56Sopenharmony_ci
3637db96d56Sopenharmony_ci   .. _asyncio_example_barrier:
3647db96d56Sopenharmony_ci
3657db96d56Sopenharmony_ci   Example::
3667db96d56Sopenharmony_ci
3677db96d56Sopenharmony_ci      async def example_barrier():
3687db96d56Sopenharmony_ci         # barrier with 3 parties
3697db96d56Sopenharmony_ci         b = asyncio.Barrier(3)
3707db96d56Sopenharmony_ci
3717db96d56Sopenharmony_ci         # create 2 new waiting tasks
3727db96d56Sopenharmony_ci         asyncio.create_task(b.wait())
3737db96d56Sopenharmony_ci         asyncio.create_task(b.wait())
3747db96d56Sopenharmony_ci
3757db96d56Sopenharmony_ci         await asyncio.sleep(0)
3767db96d56Sopenharmony_ci         print(b)
3777db96d56Sopenharmony_ci
3787db96d56Sopenharmony_ci         # The third .wait() call passes the barrier
3797db96d56Sopenharmony_ci         await b.wait()
3807db96d56Sopenharmony_ci         print(b)
3817db96d56Sopenharmony_ci         print("barrier passed")
3827db96d56Sopenharmony_ci
3837db96d56Sopenharmony_ci         await asyncio.sleep(0)
3847db96d56Sopenharmony_ci         print(b)
3857db96d56Sopenharmony_ci
3867db96d56Sopenharmony_ci      asyncio.run(example_barrier())
3877db96d56Sopenharmony_ci
3887db96d56Sopenharmony_ci   Result of this example is::
3897db96d56Sopenharmony_ci
3907db96d56Sopenharmony_ci      <asyncio.locks.Barrier object at 0x... [filling, waiters:2/3]>
3917db96d56Sopenharmony_ci      <asyncio.locks.Barrier object at 0x... [draining, waiters:0/3]>
3927db96d56Sopenharmony_ci      barrier passed
3937db96d56Sopenharmony_ci      <asyncio.locks.Barrier object at 0x... [filling, waiters:0/3]>
3947db96d56Sopenharmony_ci
3957db96d56Sopenharmony_ci   .. versionadded:: 3.11
3967db96d56Sopenharmony_ci
3977db96d56Sopenharmony_ci   .. coroutinemethod:: wait()
3987db96d56Sopenharmony_ci
3997db96d56Sopenharmony_ci      Pass the barrier. When all the tasks party to the barrier have called
4007db96d56Sopenharmony_ci      this function, they are all unblocked simultaneously.
4017db96d56Sopenharmony_ci
4027db96d56Sopenharmony_ci      When a waiting or blocked task in the barrier is cancelled,
4037db96d56Sopenharmony_ci      this task exits the barrier which stays in the same state.
4047db96d56Sopenharmony_ci      If the state of the barrier is "filling", the number of waiting task
4057db96d56Sopenharmony_ci      decreases by 1.
4067db96d56Sopenharmony_ci
4077db96d56Sopenharmony_ci      The return value is an integer in the range of 0 to ``parties-1``, different
4087db96d56Sopenharmony_ci      for each task. This can be used to select a task to do some special
4097db96d56Sopenharmony_ci      housekeeping, e.g.::
4107db96d56Sopenharmony_ci
4117db96d56Sopenharmony_ci         ...
4127db96d56Sopenharmony_ci         async with barrier as position:
4137db96d56Sopenharmony_ci            if position == 0:
4147db96d56Sopenharmony_ci               # Only one task prints this
4157db96d56Sopenharmony_ci               print('End of *draining phase*')
4167db96d56Sopenharmony_ci
4177db96d56Sopenharmony_ci      This method may raise a :class:`BrokenBarrierError` exception if the
4187db96d56Sopenharmony_ci      barrier is broken or reset while a task is waiting.
4197db96d56Sopenharmony_ci      It could raise a :exc:`CancelledError` if a task is cancelled.
4207db96d56Sopenharmony_ci
4217db96d56Sopenharmony_ci   .. coroutinemethod:: reset()
4227db96d56Sopenharmony_ci
4237db96d56Sopenharmony_ci      Return the barrier to the default, empty state.  Any tasks waiting on it
4247db96d56Sopenharmony_ci      will receive the :class:`BrokenBarrierError` exception.
4257db96d56Sopenharmony_ci
4267db96d56Sopenharmony_ci      If a barrier is broken it may be better to just leave it and create a new one.
4277db96d56Sopenharmony_ci
4287db96d56Sopenharmony_ci   .. coroutinemethod:: abort()
4297db96d56Sopenharmony_ci
4307db96d56Sopenharmony_ci      Put the barrier into a broken state.  This causes any active or future
4317db96d56Sopenharmony_ci      calls to :meth:`wait` to fail with the :class:`BrokenBarrierError`.
4327db96d56Sopenharmony_ci      Use this for example if one of the tasks needs to abort, to avoid infinite
4337db96d56Sopenharmony_ci      waiting tasks.
4347db96d56Sopenharmony_ci
4357db96d56Sopenharmony_ci   .. attribute:: parties
4367db96d56Sopenharmony_ci
4377db96d56Sopenharmony_ci      The number of tasks required to pass the barrier.
4387db96d56Sopenharmony_ci
4397db96d56Sopenharmony_ci   .. attribute:: n_waiting
4407db96d56Sopenharmony_ci
4417db96d56Sopenharmony_ci      The number of tasks currently waiting in the barrier while filling.
4427db96d56Sopenharmony_ci
4437db96d56Sopenharmony_ci   .. attribute:: broken
4447db96d56Sopenharmony_ci
4457db96d56Sopenharmony_ci      A boolean that is ``True`` if the barrier is in the broken state.
4467db96d56Sopenharmony_ci
4477db96d56Sopenharmony_ci
4487db96d56Sopenharmony_ci.. exception:: BrokenBarrierError
4497db96d56Sopenharmony_ci
4507db96d56Sopenharmony_ci   This exception, a subclass of :exc:`RuntimeError`, is raised when the
4517db96d56Sopenharmony_ci   :class:`Barrier` object is reset or broken.
4527db96d56Sopenharmony_ci
4537db96d56Sopenharmony_ci---------
4547db96d56Sopenharmony_ci
4557db96d56Sopenharmony_ci
4567db96d56Sopenharmony_ci.. versionchanged:: 3.9
4577db96d56Sopenharmony_ci
4587db96d56Sopenharmony_ci   Acquiring a lock using ``await lock`` or ``yield from lock`` and/or
4597db96d56Sopenharmony_ci   :keyword:`with` statement (``with await lock``, ``with (yield from
4607db96d56Sopenharmony_ci   lock)``) was removed.  Use ``async with lock`` instead.
461