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