Skip to content

Commit f0054be

Browse files
committed
Tutorial: Impove section on Lock primitive.
1 parent c79fb00 commit f0054be

File tree

1 file changed

+26
-18
lines changed

1 file changed

+26
-18
lines changed

v3/docs/TUTORIAL.md

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -627,17 +627,28 @@ This guarantees unique access to a shared resource. In the following code
627627
sample a `Lock` instance `lock` has been created and is passed to all tasks
628628
wishing to access the shared resource. Each task attempts to acquire the lock,
629629
pausing execution until it succeeds.
630+
```python
631+
from asyncio import Lock
632+
lock = Lock()
633+
```
634+
Synchronous methods:
635+
* `locked` No args. Returns `True` if locked.
636+
* `release` No args. Releases the lock. See note below.
637+
Asynchronous method:
638+
* `acquire` No args. Pauses until the lock has been acquired. Use by executing
639+
`await lock.acquire()`.
630640

641+
A task waiting on a lock may be cancelled or may be run subject to a timeout.
642+
The normal way to use a `Lock` is in a context manager:
631643
```python
632644
import asyncio
633645
from asyncio import Lock
634646

635647
async def task(i, lock):
636648
while 1:
637-
await lock.acquire()
638-
print("Acquired lock in task", i)
639-
await asyncio.sleep(0.5)
640-
lock.release()
649+
async with lock:
650+
print("Acquired lock in task", i)
651+
await asyncio.sleep(0.5)
641652

642653
async def main():
643654
lock = Lock() # The Lock instance
@@ -648,26 +659,24 @@ async def main():
648659

649660
asyncio.run(main()) # Run for 10s
650661
```
662+
Use of a context manager is strongly recommended - otherwise an application must
663+
ensure that `.release` is only ever called when that same task has called
664+
`.locked`. Calling `.release` on an unlocked `Lock` will raise a `ValueError`.
665+
Calling it on a `Lock` which has been locked by another task will cause that
666+
second task to produce a `ValueError` when it attempts to release the `Lock` or
667+
when its context manager exits. Context managers avoid these issues.
651668

652-
Methods:
653-
654-
* `locked` No args. Returns `True` if locked.
655-
* `release` No args. Releases the lock.
656-
* `acquire` No args. Coro which pauses until the lock has been acquired. Use
657-
by executing `await lock.acquire()`.
658-
659-
A task waiting on a lock may be cancelled or may be run subject to a timeout.
660-
The normal way to use a `Lock` is in a context manager:
661-
669+
For the brave the following illustrates use without a CM.
662670
```python
663671
import asyncio
664672
from asyncio import Lock
665673

666674
async def task(i, lock):
667675
while 1:
668-
async with lock:
669-
print("Acquired lock in task", i)
670-
await asyncio.sleep(0.5)
676+
await lock.acquire()
677+
print("Acquired lock in task", i)
678+
await asyncio.sleep(0.5)
679+
lock.release()
671680

672681
async def main():
673682
lock = Lock() # The Lock instance
@@ -678,7 +687,6 @@ async def main():
678687

679688
asyncio.run(main()) # Run for 10s
680689
```
681-
682690
###### [Contents](./TUTORIAL.md#contents)
683691

684692
## 3.2 Event

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy