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