@@ -13,9 +13,9 @@ notifying other tasks and guarding access to shared resources.
1313Events
1414------
1515
16- Events are used to notify tasks that something they've been waiting to happen has
17- happened. An event object can have multiple listeners and they are all notified when the
18- event is triggered.
16+ Events ( :class: ` Event `) are used to notify tasks that something they've been waiting to
17+ happen has happened. An event object can have multiple listeners and they are all
18+ notified when the event is triggered.
1919
2020Example::
2121
@@ -35,17 +35,20 @@ Example::
3535
3636 run(main)
3737
38+ # Output:
39+ # Received notification!
40+
3841.. note :: Unlike standard library Events, AnyIO events cannot be reused, and must be
3942 replaced instead. This practice prevents a class of race conditions, and matches the
4043 semantics of the Trio library.
4144
4245Semaphores
4346----------
4447
45- Semaphores are used for limiting access to a shared resource. A semaphore starts with a
46- maximum value, which is decremented each time the semaphore is acquired by a task and
47- incremented when it is released. If the value drops to zero, any attempt to acquire the
48- semaphore will block until another task frees it.
48+ Semaphores ( :class: ` Semaphore `) are used for limiting access to a shared resource. A
49+ semaphore starts with a maximum value, which is decremented each time the semaphore is
50+ acquired by a task and incremented when it is released. If the value drops to zero, any
51+ attempt to acquire the semaphore will block until another task frees it.
4952
5053Example::
5154
@@ -54,7 +57,7 @@ Example::
5457
5558 async def use_resource(tasknum, semaphore):
5659 async with semaphore:
57- print(' Task number', tasknum, ' is now working with the shared resource' )
60+ print(f" Task number { tasknum} is now working with the shared resource" )
5861 await sleep(1)
5962
6063
@@ -66,6 +69,18 @@ Example::
6669
6770 run(main)
6871
72+ # Output:
73+ # Task number 0 is now working with the shared resource
74+ # Task number 1 is now working with the shared resource
75+ # Task number 2 is now working with the shared resource
76+ # Task number 3 is now working with the shared resource
77+ # Task number 4 is now working with the shared resource
78+ # Task number 5 is now working with the shared resource
79+ # Task number 6 is now working with the shared resource
80+ # Task number 7 is now working with the shared resource
81+ # Task number 8 is now working with the shared resource
82+ # Task number 9 is now working with the shared resource
83+
6984.. tip :: If the performance of semaphores is critical for you, you could pass
7085 ``fast_acquire=True `` to :class: `Semaphore `. This has the effect of skipping the
7186 :func: `~.lowlevel.cancel_shielded_checkpoint ` call in :meth: `Semaphore.acquire ` if
@@ -76,9 +91,9 @@ Example::
7691Locks
7792-----
7893
79- Locks are used to guard shared resources to ensure sole access to a single task at once.
80- They function much like semaphores with a maximum value of 1, except that only the task
81- that acquired the lock is allowed to release it.
94+ Locks ( :class: ` Lock `) are used to guard shared resources to ensure sole access to a
95+ single task at once. They function much like semaphores with a maximum value of 1,
96+ except that only the task that acquired the lock is allowed to release it.
8297
8398Example::
8499
@@ -99,6 +114,12 @@ Example::
99114
100115 run(main)
101116
117+ # Output:
118+ # Task number 0 is now working with the shared resource
119+ # Task number 1 is now working with the shared resource
120+ # Task number 2 is now working with the shared resource
121+ # Task number 3 is now working with the shared resource
122+
102123.. tip :: If the performance of locks is critical for you, you could pass
103124 ``fast_acquire=True `` to :class: `Lock `. This has the effect of skipping the
104125 :func: `~.lowlevel.cancel_shielded_checkpoint ` call in :meth: `Lock.acquire ` if there
@@ -148,12 +169,31 @@ Example::
148169
149170 run(main)
150171
172+ # Output:
173+ # Woke up task number 0
174+ # Woke up task number 1
175+ # Woke up task number 2
176+ # Woke up task number 3
177+ # Woke up task number 4
178+ # Woke up task number 5
179+
180+ .. _capacity-limiters :
181+
151182Capacity limiters
152183-----------------
153184
154- Capacity limiters are like semaphores except that a single borrower (the current task by
155- default) can only hold a single token at a time. It is also possible to borrow a token
156- on behalf of any arbitrary object, so long as that object is hashable.
185+ Capacity limiters (:class: `CapacityLimiter `) are like semaphores except that a single
186+ borrower (the current task by default) can only hold a single token at a time. It is
187+ also possible to borrow a token on behalf of any arbitrary object, so long as that object
188+ is hashable.
189+
190+ It is recommended to use capacity limiters instead of semaphores unless you intend to
191+ allow a task to acquire multiple tokens from the same object. AnyIO uses capacity
192+ limiters to limit the number of threads spawned.
193+
194+ The number of total tokens available for tasks to acquire can be adjusted by assigning
195+ the desired value to the ``total_tokens `` property. If the value is higher than the
196+ previous one, it will automatically wake up the appropriate number of waiting tasks.
157197
158198Example::
159199
@@ -162,7 +202,7 @@ Example::
162202
163203 async def use_resource(tasknum, limiter):
164204 async with limiter:
165- print(' Task number', tasknum, ' is now working with the shared resource' )
205+ print(f" Task number { tasknum} is now working with the shared resource" )
166206 await sleep(1)
167207
168208
@@ -174,8 +214,17 @@ Example::
174214
175215 run(main)
176216
177- You can adjust the total number of tokens by setting a different value on the limiter's
178- ``total_tokens `` property.
217+ # Output:
218+ # Task number 0 is now working with the shared resource
219+ # Task number 1 is now working with the shared resource
220+ # Task number 2 is now working with the shared resource
221+ # Task number 3 is now working with the shared resource
222+ # Task number 4 is now working with the shared resource
223+ # Task number 5 is now working with the shared resource
224+ # Task number 6 is now working with the shared resource
225+ # Task number 7 is now working with the shared resource
226+ # Task number 8 is now working with the shared resource
227+ # Task number 9 is now working with the shared resource
179228
180229Resource guards
181230---------------
0 commit comments