“Python/docs/3.9/library/asyncio-sync”的版本间差异

来自菜鸟教程
Python/docs/3.9/library/asyncio-sync
跳转至:导航、​搜索
(autoload)
 
(Page commit)
 
第1行: 第1行:
 +
{{DISPLAYTITLE:同步原语 — Python 文档}}
 
<div id="synchronization-primitives" class="section">
 
<div id="synchronization-primitives" class="section">
  
 
<span id="asyncio-sync"></span>
 
<span id="asyncio-sync"></span>
= Synchronization Primitives =
+
= 同步原语 =
  
'''Source code:''' [https://github.com/python/cpython/tree/3.9/Lib/asyncio/locks.py Lib/asyncio/locks.py]
+
'''源代码:''' [[#id1|<span id="id2" class="problematic">:source:`Lib/asyncio/locks.py`</span>]]
  
asyncio synchronization primitives are designed to be similar to
 
those of the [[../threading#module-threading|<code>threading</code>]] module with two important caveats:
 
  
* asyncio primitives are not thread-safe, therefore they should not be used for OS thread synchronization (use [[../threading#module-threading|<code>threading</code>]] for that);
+
-----
* methods of these synchronization primitives do not accept the ''timeout'' argument; use the [[../asyncio-task#asyncio|<code>asyncio.wait_for()</code>]] function to perform operations with timeouts.
 
  
asyncio has the following basic synchronization primitives:
+
asyncio 同步原语被设计为类似于 [[../threading#module-threading|threading]] 模块的那些,但有两个重要的警告:
 +
 
 +
* asyncio 原语不是线程安全的,因此它们不应该用于 OS 线程同步(为此使用 [[../threading#module-threading|threading]]);
 +
* 这些同步原语的方法不接受 ''timeout'' 参数; 使用 <code>asyncio.wait_for()</code> 函数执行超时操作。
 +
 
 +
asyncio 具有以下基本同步原语:
  
 
* [[#asyncio.Lock|<code>Lock</code>]]
 
* [[#asyncio.Lock|<code>Lock</code>]]
第19行: 第22行:
 
* [[#asyncio.Semaphore|<code>Semaphore</code>]]
 
* [[#asyncio.Semaphore|<code>Semaphore</code>]]
 
* [[#asyncio.BoundedSemaphore|<code>BoundedSemaphore</code>]]
 
* [[#asyncio.BoundedSemaphore|<code>BoundedSemaphore</code>]]
 +
 +
 +
-----
  
 
<div id="lock" class="section">
 
<div id="lock" class="section">
  
== Lock ==
+
== ==
  
 
<dl>
 
<dl>
<dt>''class'' <code>asyncio.</code><code>Lock</code><span class="sig-paren">(</span>''\*'', ''loop=None''<span class="sig-paren">)</span></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">asyncio.</span></span><span class="sig-name descname"><span class="pre">Lock</span></span><span class="sig-paren">(</span>''<span class="pre">\*</span>'', ''<span class="pre">loop=None</span>''<span class="sig-paren">)</span></dt>
<dd><p>Implements a mutex lock for asyncio tasks. Not thread-safe.</p>
+
<dd><p>为异步任务实现互斥锁。 不是线程安全的。</p>
<p>An asyncio lock can be used to guarantee exclusive access to a
+
<p>异步锁可用于保证对共享资源的独占访问。</p>
shared resource.</p>
+
<p>使用 Lock 的首选方法是 [[../../reference/compound_stmts#async-with|async with]] 语句:</p>
<p>The preferred way to use a Lock is an [[../../reference/compound_stmts#async-with|<code>async with</code>]]
 
statement:</p>
 
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>lock = asyncio.Lock()
+
<syntaxhighlight lang="python3">lock = asyncio.Lock()
  
 
# ... later
 
# ... later
 
async with lock:
 
async with lock:
     # access shared state</pre>
+
     # access shared state</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
<p>which is equivalent to:</p>
+
<p>这相当于:</p>
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>lock = asyncio.Lock()
+
<syntaxhighlight lang="python3">lock = asyncio.Lock()
  
 
# ... later
 
# ... later
第56行: 第60行:
 
     # access shared state
 
     # access shared state
 
finally:
 
finally:
     lock.release()</pre>
+
     lock.release()</syntaxhighlight>
 
 
</div>
 
  
 
</div>
 
</div>
<div class="deprecated-removed">
 
 
<p><span class="versionmodified">Deprecated since version 3.8, will be removed in version 3.10: </span>The ''loop'' parameter.</p>
 
  
 
</div>
 
</div>
 
<dl>
 
<dl>
<dt>''coroutine'' <code>acquire</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">release</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Acquire the lock.</p>
+
<dd><p>释放锁。</p>
<p>This method waits until the lock is ''unlocked'', sets it to
+
<p>当锁定为''locked''时,将其重置为''unlocked''并返回。</p>
''locked'' and returns <code>True</code>.</p>
+
<p>如果锁是 ''unlocked'',则会引发 [[../exceptions#RuntimeError|RuntimeError]]</p></dd></dl>
<p>When more than one coroutine is blocked in [[#asyncio.Lock.acquire|<code>acquire()</code>]]
 
waiting for the lock to be unlocked, only one coroutine
 
eventually proceeds.</p>
 
<p>Acquiring a lock is ''fair'': the coroutine that proceeds will be
 
the first coroutine that started waiting on the lock.</p></dd></dl>
 
 
 
<dl>
 
<dt><code>release</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
 
<dd><p>Release the lock.</p>
 
<p>When the lock is ''locked'', reset it to ''unlocked'' and return.</p>
 
<p>If the lock is ''unlocked'', a [[../exceptions#RuntimeError|<code>RuntimeError</code>]] is raised.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>locked</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">locked</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Return <code>True</code> if the lock is ''locked''.</p></dd></dl>
+
<dd><p>如果锁是 ''locked'',则返回 <code>True</code></p></dd></dl>
 
</dd></dl>
 
</dd></dl>
  
第92行: 第80行:
 
<div id="event" class="section">
 
<div id="event" class="section">
  
== Event ==
+
== 事件 ==
  
 
<dl>
 
<dl>
<dt>''class'' <code>asyncio.</code><code>Event</code><span class="sig-paren">(</span>''\*'', ''loop=None''<span class="sig-paren">)</span></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">asyncio.</span></span><span class="sig-name descname"><span class="pre">Event</span></span><span class="sig-paren">(</span>''<span class="pre">\*</span>'', ''<span class="pre">loop=None</span>''<span class="sig-paren">)</span></dt>
<dd><p>An event object. Not thread-safe.</p>
+
<dd><p>一个事件对象。 不是线程安全的。</p>
<p>An asyncio event can be used to notify multiple asyncio tasks
+
<p>一个 asyncio 事件可用于通知多个 asyncio 任务某个事件已经发生。</p>
that some event has happened.</p>
+
<p>事件对象管理一个内部标志,可以使用 [[#asyncio.Event.set|set()]] 方法将其设置为 ''true'',并使用 clear()[ 重置为 ''false''[ X153X] 方法。 <code>wait()</code> 方法阻塞,直到标志设置为 ''true''。 该标志最初设置为 ''false''</p>
<p>An Event object manages an internal flag that can be set to ''true''
+
<p>例子:</p>
with the [[../stdtypes#set|<code>set()</code>]] method and reset to ''false'' with the
 
[[#asyncio.Event.clear|<code>clear()</code>]] method. The [[../asyncio-task#asyncio|<code>wait()</code>]] method blocks until the
 
flag is set to ''true''. The flag is set to ''false'' initially.</p>
 
<div class="deprecated-removed">
 
 
 
<p><span class="versionmodified">Deprecated since version 3.8, will be removed in version 3.10: </span>The ''loop'' parameter.</p>
 
 
 
</div>
 
<p>Example:</p>
 
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>async def waiter(event):
+
<syntaxhighlight lang="python3">async def waiter(event):
 
     print('waiting for it ...')
 
     print('waiting for it ...')
 
     await event.wait()
 
     await event.wait()
第132行: 第111行:
 
     await waiter_task
 
     await waiter_task
  
asyncio.run(main())</pre>
+
asyncio.run(main())</syntaxhighlight>
  
 
</div>
 
</div>
第138行: 第117行:
 
</div>
 
</div>
 
<dl>
 
<dl>
<dt>''coroutine'' <code>wait</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">set</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Wait until the event is set.</p>
+
<dd><p>设置事件。</p>
<p>If the event is set, return <code>True</code> immediately.
+
<p>所有等待事件设置的任务将立即被唤醒。</p></dd></dl>
Otherwise block until another task calls [[../stdtypes#set|<code>set()</code>]].</p></dd></dl>
 
 
 
<dl>
 
<dt><code>set</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
 
<dd><p>Set the event.</p>
 
<p>All tasks waiting for event to be set will be immediately
 
awakened.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>clear</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">clear</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Clear (unset) the event.</p>
+
<dd><p>清除(取消设置)事件。</p>
<p>Tasks awaiting on [[../asyncio-task#asyncio|<code>wait()</code>]] will now block until the
+
<p><code>wait()</code> 上等待的任务现在将阻塞,直到再次调用 [[#asyncio.Event.set|set()]] 方法。</p></dd></dl>
[[../stdtypes#set|<code>set()</code>]] method is called again.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>is_set</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">is_set</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Return <code>True</code> if the event is set.</p></dd></dl>
+
<dd><p>如果设置了事件,则返回 <code>True</code></p></dd></dl>
 
</dd></dl>
 
</dd></dl>
  
第164行: 第135行:
 
<div id="condition" class="section">
 
<div id="condition" class="section">
  
== Condition ==
+
== 状况 ==
  
 
<dl>
 
<dl>
<dt>''class'' <code>asyncio.</code><code>Condition</code><span class="sig-paren">(</span>''lock=None'', ''\*'', ''loop=None''<span class="sig-paren">)</span></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">asyncio.</span></span><span class="sig-name descname"><span class="pre">Condition</span></span><span class="sig-paren">(</span>''<span class="pre">lock=None</span>'', ''<span class="pre">\*</span>'', ''<span class="pre">loop=None</span>''<span class="sig-paren">)</span></dt>
<dd><p>A Condition object. Not thread-safe.</p>
+
<dd><p>一个条件对象。 不是线程安全的。</p>
<p>An asyncio condition primitive can be used by a task to wait for
+
<p>任务可以使用异步条件原语来等待某个事件发生,然后获得对共享资源的独占访问权限。</p>
some event to happen and then get exclusive access to a shared
+
<p>本质上,Condition 对象结合了 [[#asyncio.Event|Event]] [[#asyncio.Lock|Lock]] 的功能。 可以让多个 Condition 对象共享一个 Lock,这允许在对共享资源的特定状态感兴趣的不同任务之间协调对共享资源的独占访问。</p>
resource.</p>
+
<p>可选的 ''lock'' 参数必须是 [[#asyncio.Lock|Lock]] 对象或 <code>None</code>。 在后一种情况下,会自动创建一个新的 Lock 对象。</p>
<p>In essence, a Condition object combines the functionality
+
<p>使用条件的首选方法是 [[../../reference/compound_stmts#async-with|async with]] 语句:</p>
of an [[#asyncio.Event|<code>Event</code>]] and a [[#asyncio.Lock|<code>Lock</code>]]. It is possible to have
 
multiple Condition objects share one Lock, which allows coordinating
 
exclusive access to a shared resource between different tasks
 
interested in particular states of that shared resource.</p>
 
<p>The optional ''lock'' argument must be a [[#asyncio.Lock|<code>Lock</code>]] object or
 
<code>None</code>. In the latter case a new Lock object is created
 
automatically.</p>
 
<div class="deprecated-removed">
 
 
 
<p><span class="versionmodified">Deprecated since version 3.8, will be removed in version 3.10: </span>The ''loop'' parameter.</p>
 
 
 
</div>
 
<p>The preferred way to use a Condition is an [[../../reference/compound_stmts#async-with|<code>async with</code>]]
 
statement:</p>
 
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>cond = asyncio.Condition()
+
<syntaxhighlight lang="python3">cond = asyncio.Condition()
  
 
# ... later
 
# ... later
 
async with cond:
 
async with cond:
     await cond.wait()</pre>
+
     await cond.wait()</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
<p>which is equivalent to:</p>
+
<p>这相当于:</p>
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>cond = asyncio.Condition()
+
<syntaxhighlight lang="python3">cond = asyncio.Condition()
  
 
# ... later
 
# ... later
第212行: 第169行:
 
     await cond.wait()
 
     await cond.wait()
 
finally:
 
finally:
     cond.release()</pre>
+
     cond.release()</syntaxhighlight>
  
 
</div>
 
</div>
第218行: 第175行:
 
</div>
 
</div>
 
<dl>
 
<dl>
<dt>''coroutine'' <code>acquire</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">notify</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">n</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">1</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Acquire the underlying lock.</p>
+
<dd><p>在此条件下最多唤醒 ''n'' 个任务(默认为 1 个)。 如果没有任务在等待,则该方法为空操作。</p>
<p>This method waits until the underlying lock is ''unlocked'',
+
<p>必须在调用此方法之前获取锁,并在不久之后释放锁。 如果使用 ''unlocked'' 锁调用,则会引发 [[../exceptions#RuntimeError|RuntimeError]] 错误。</p></dd></dl>
sets it to ''locked'' and returns <code>True</code>.</p></dd></dl>
 
 
 
<dl>
 
<dt><code>notify</code><span class="sig-paren">(</span>''<span class="n">n</span><span class="o">=</span><span class="default_value">1</span>''<span class="sig-paren">)</span></dt>
 
<dd><p>Wake up at most ''n'' tasks (1 by default) waiting on this
 
condition. The method is no-op if no tasks are waiting.</p>
 
<p>The lock must be acquired before this method is called and
 
released shortly after. If called with an ''unlocked'' lock
 
a [[../exceptions#RuntimeError|<code>RuntimeError</code>]] error is raised.</p></dd></dl>
 
 
 
<dl>
 
<dt><code>locked</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
 
<dd><p>Return <code>True</code> if the underlying lock is acquired.</p></dd></dl>
 
 
 
<dl>
 
<dt><code>notify_all</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
 
<dd><p>Wake up all tasks waiting on this condition.</p>
 
<p>This method acts like [[#asyncio.Condition.notify|<code>notify()</code>]], but wakes up all waiting
 
tasks.</p>
 
<p>The lock must be acquired before this method is called and
 
released shortly after. If called with an ''unlocked'' lock
 
a [[../exceptions#RuntimeError|<code>RuntimeError</code>]] error is raised.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>release</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">locked</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Release the underlying lock.</p>
+
<dd><p>如果获取了底层锁,则返回 <code>True</code></p></dd></dl>
<p>When invoked on an unlocked lock, a [[../exceptions#RuntimeError|<code>RuntimeError</code>]] is
 
raised.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt>''coroutine'' <code>wait</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">notify_all</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Wait until notified.</p>
+
<dd><p>唤醒所有在此条件下等待的任务。</p>
<p>If the calling task has not acquired the lock when this method is
+
<p>此方法的作用类似于 [[#asyncio.Condition.notify|notify()]],但会唤醒所有等待的任务。</p>
called, a [[../exceptions#RuntimeError|<code>RuntimeError</code>]] is raised.</p>
+
<p>必须在调用此方法之前获取锁,并在不久之后释放锁。 如果使用 ''unlocked'' 锁调用,则会引发 [[../exceptions#RuntimeError|RuntimeError]] 错误。</p></dd></dl>
<p>This method releases the underlying lock, and then blocks until
 
it is awakened by a [[#asyncio.Condition.notify|<code>notify()</code>]] or [[#asyncio.Condition.notify_all|<code>notify_all()</code>]] call.
 
Once awakened, the Condition re-acquires its lock and this method
 
returns <code>True</code>.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt>''coroutine'' <code>wait_for</code><span class="sig-paren">(</span>''<span class="n">predicate</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">release</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Wait until a predicate becomes ''true''.</p>
+
<dd><p>释放底层锁。</p>
<p>The predicate must be a callable which result will be
+
<p>当在解锁的锁上调用时,会引发 [[../exceptions#RuntimeError|RuntimeError]]。</p></dd></dl>
interpreted as a boolean value. The final value is the
 
return value.</p></dd></dl>
 
 
</dd></dl>
 
</dd></dl>
  
第272行: 第199行:
 
<div id="semaphore" class="section">
 
<div id="semaphore" class="section">
  
== Semaphore ==
+
== 信号 ==
  
 
<dl>
 
<dl>
<dt>''class'' <code>asyncio.</code><code>Semaphore</code><span class="sig-paren">(</span>''value=1'', ''\*'', ''loop=None''<span class="sig-paren">)</span></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">asyncio.</span></span><span class="sig-name descname"><span class="pre">Semaphore</span></span><span class="sig-paren">(</span>''<span class="pre">value=1</span>'', ''<span class="pre">\*</span>'', ''<span class="pre">loop=None</span>''<span class="sig-paren">)</span></dt>
<dd><p>A Semaphore object. Not thread-safe.</p>
+
<dd><p>一个信号量对象。 不是线程安全的。</p>
<p>A semaphore manages an internal counter which is decremented by each
+
<p>信号量管理一个内部计数器,该计数器由每个 <code>acquire()</code> 调用递减,并由每个 [[#asyncio.Semaphore.release|release()]] 调用递增。 计数器永远不会低于零; 当 <code>acquire()</code> 发现它为零时,它会阻塞,直到某个任务调用 [[#asyncio.Semaphore.release|release()]]</p>
[[#asyncio.Semaphore.acquire|<code>acquire()</code>]] call and incremented by each [[#asyncio.Semaphore.release|<code>release()</code>]] call.
+
<p>可选的 ''value'' 参数给出内部计数器的初始值(默认为 <code>1</code>)。 如果给定值小于 <code>0</code>,则会引发 [[../exceptions#ValueError|ValueError]]</p>
The counter can never go below zero; when [[#asyncio.Semaphore.acquire|<code>acquire()</code>]] finds
+
<p>使用信号量的首选方法是 [[../../reference/compound_stmts#async-with|async with]] 语句:</p>
that it is zero, it blocks, waiting until some task calls
 
[[#asyncio.Semaphore.release|<code>release()</code>]].</p>
 
<p>The optional ''value'' argument gives the initial value for the
 
internal counter (<code>1</code> by default). If the given value is
 
less than <code>0</code> a [[../exceptions#ValueError|<code>ValueError</code>]] is raised.</p>
 
<div class="deprecated-removed">
 
 
 
<p><span class="versionmodified">Deprecated since version 3.8, will be removed in version 3.10: </span>The ''loop'' parameter.</p>
 
 
 
</div>
 
<p>The preferred way to use a Semaphore is an [[../../reference/compound_stmts#async-with|<code>async with</code>]]
 
statement:</p>
 
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>sem = asyncio.Semaphore(10)
+
<syntaxhighlight lang="python3">sem = asyncio.Semaphore(10)
  
 
# ... later
 
# ... later
 
async with sem:
 
async with sem:
     # work with shared resource</pre>
+
     # work with shared resource</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
<p>which is equivalent to:</p>
+
<p>这相当于:</p>
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>sem = asyncio.Semaphore(10)
+
<syntaxhighlight lang="python3">sem = asyncio.Semaphore(10)
  
 
# ... later
 
# ... later
第317行: 第232行:
 
     # work with shared resource
 
     # work with shared resource
 
finally:
 
finally:
     sem.release()</pre>
+
     sem.release()</syntaxhighlight>
  
 
</div>
 
</div>
第323行: 第238行:
 
</div>
 
</div>
 
<dl>
 
<dl>
<dt>''coroutine'' <code>acquire</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">locked</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Acquire a semaphore.</p>
+
<dd><p>如果不能立即获取信号量,则返回 <code>True</code></p></dd></dl>
<p>If the internal counter is greater than zero, decrement
 
it by one and return <code>True</code> immediately. If it is zero, wait
 
until a [[#asyncio.Semaphore.release|<code>release()</code>]] is called and return <code>True</code>.</p></dd></dl>
 
 
 
<dl>
 
<dt><code>locked</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
 
<dd><p>Returns <code>True</code> if semaphore can not be acquired immediately.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>release</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">release</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Release a semaphore, incrementing the internal counter by one.
+
<dd><p>释放信号量,将内部计数器加一。 可以唤醒一个等待获取信号量的任务。</p>
Can wake up a task waiting to acquire the semaphore.</p>
+
<p>[[#asyncio.BoundedSemaphore|BoundedSemaphore]] 不同,[[#asyncio.Semaphore|Semaphore]] 允许进行比 <code>acquire()</code> 调用更多的 <code>release()</code> 调用。</p></dd></dl>
<p>Unlike [[#asyncio.BoundedSemaphore|<code>BoundedSemaphore</code>]], [[#asyncio.Semaphore|<code>Semaphore</code>]] allows
 
making more <code>release()</code> calls than <code>acquire()</code> calls.</p></dd></dl>
 
 
</dd></dl>
 
</dd></dl>
  
第345行: 第251行:
 
<div id="boundedsemaphore" class="section">
 
<div id="boundedsemaphore" class="section">
  
== BoundedSemaphore ==
+
== 有界信号量 ==
  
 
<dl>
 
<dl>
<dt>''class'' <code>asyncio.</code><code>BoundedSemaphore</code><span class="sig-paren">(</span>''value=1'', ''\*'', ''loop=None''<span class="sig-paren">)</span></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">asyncio.</span></span><span class="sig-name descname"><span class="pre">BoundedSemaphore</span></span><span class="sig-paren">(</span>''<span class="pre">value=1</span>'', ''<span class="pre">\*</span>'', ''<span class="pre">loop=None</span>''<span class="sig-paren">)</span></dt>
<dd><p>A bounded semaphore object. Not thread-safe.</p>
+
<dd><p>有界信号量对象。 不是线程安全的。</p>
<p>Bounded Semaphore is a version of [[#asyncio.Semaphore|<code>Semaphore</code>]] that raises
+
<p>有界信号量是 [[#asyncio.Semaphore|Semaphore]] 的一个版本,如果将内部计数器增加到初始 ''值'' 以上,则会在 [[#asyncio.Semaphore.release|release()]] 中引发 [[../exceptions#ValueError|ValueError]]</p></dd></dl>
a [[../exceptions#ValueError|<code>ValueError</code>]] in [[#asyncio.Semaphore.release|<code>release()</code>]] if it
 
increases the internal counter above the initial ''value''.</p>
 
<div class="deprecated-removed">
 
  
<p><span class="versionmodified">Deprecated since version 3.8, will be removed in version 3.10: </span>The ''loop'' parameter.</p>
 
  
</div></dd></dl>
+
-----
  
 
<div class="versionchanged">
 
<div class="versionchanged">
  
<span class="versionmodified changed">3.9 版更改: </span>Acquiring a lock using <code>await lock</code> or <code>yield from lock</code> and/or
+
<span class="versionmodified changed">3.9 版更改:</span>使用 <code>await lock</code> <code>yield from lock</code> /[[../../reference/compound_stmts#with|with]] 语句获取锁(<code>with await lock</code><code>with (yield from lock)</code>) 被移除。 请改用 <code>async with lock</code>
[[../../reference/compound_stmts#with|<code>with</code>]] statement (<code>with await lock</code>, <code>with (yield from lock)</code>) was removed. Use <code>async with lock</code> instead.
+
 
  
 +
</div>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
 +
<div class="clearer">
 +
 +
  
 
</div>
 
</div>
  
[[Category:Python 3.9 中文文档]]
+
[[Category:Python 3.9 文档]]

2021年10月31日 (日) 04:51的最新版本

同步原语

源代码: :source:`Lib/asyncio/locks.py`



asyncio 同步原语被设计为类似于 threading 模块的那些,但有两个重要的警告:

  • asyncio 原语不是线程安全的,因此它们不应该用于 OS 线程同步(为此使用 threading);
  • 这些同步原语的方法不接受 timeout 参数; 使用 asyncio.wait_for() 函数执行超时操作。

asyncio 具有以下基本同步原语:



class asyncio.Lock(\*, loop=None)

为异步任务实现互斥锁。 不是线程安全的。

异步锁可用于保证对共享资源的独占访问。

使用 Lock 的首选方法是 async with 语句:

lock = asyncio.Lock()

# ... later
async with lock:
    # access shared state

这相当于:

lock = asyncio.Lock()

# ... later
await lock.acquire()
try:
    # access shared state
finally:
    lock.release()
release()

释放锁。

当锁定为locked时,将其重置为unlocked并返回。

如果锁是 unlocked,则会引发 RuntimeError

locked()

如果锁是 locked,则返回 True


事件

class asyncio.Event(\*, loop=None)

一个事件对象。 不是线程安全的。

一个 asyncio 事件可用于通知多个 asyncio 任务某个事件已经发生。

事件对象管理一个内部标志,可以使用 set() 方法将其设置为 true,并使用 clear()[ 重置为 false[ X153X] 方法。 wait() 方法阻塞,直到标志设置为 true。 该标志最初设置为 false

例子:

async def waiter(event):
    print('waiting for it ...')
    await event.wait()
    print('... got it!')

async def main():
    # Create an Event object.
    event = asyncio.Event()

    # Spawn a Task to wait until 'event' is set.
    waiter_task = asyncio.create_task(waiter(event))

    # Sleep for 1 second and set the event.
    await asyncio.sleep(1)
    event.set()

    # Wait until the waiter task is finished.
    await waiter_task

asyncio.run(main())
set()

设置事件。

所有等待事件设置的任务将立即被唤醒。

clear()

清除(取消设置)事件。

wait() 上等待的任务现在将阻塞,直到再次调用 set() 方法。

is_set()

如果设置了事件,则返回 True


状况

class asyncio.Condition(lock=None, \*, loop=None)

一个条件对象。 不是线程安全的。

任务可以使用异步条件原语来等待某个事件发生,然后获得对共享资源的独占访问权限。

本质上,Condition 对象结合了 EventLock 的功能。 可以让多个 Condition 对象共享一个 Lock,这允许在对共享资源的特定状态感兴趣的不同任务之间协调对共享资源的独占访问。

可选的 lock 参数必须是 Lock 对象或 None。 在后一种情况下,会自动创建一个新的 Lock 对象。

使用条件的首选方法是 async with 语句:

cond = asyncio.Condition()

# ... later
async with cond:
    await cond.wait()

这相当于:

cond = asyncio.Condition()

# ... later
await cond.acquire()
try:
    await cond.wait()
finally:
    cond.release()
notify(n=1)

在此条件下最多唤醒 n 个任务(默认为 1 个)。 如果没有任务在等待,则该方法为空操作。

必须在调用此方法之前获取锁,并在不久之后释放锁。 如果使用 unlocked 锁调用,则会引发 RuntimeError 错误。

locked()

如果获取了底层锁,则返回 True

notify_all()

唤醒所有在此条件下等待的任务。

此方法的作用类似于 notify(),但会唤醒所有等待的任务。

必须在调用此方法之前获取锁,并在不久之后释放锁。 如果使用 unlocked 锁调用,则会引发 RuntimeError 错误。

release()

释放底层锁。

当在解锁的锁上调用时,会引发 RuntimeError


信号

class asyncio.Semaphore(value=1, \*, loop=None)

一个信号量对象。 不是线程安全的。

信号量管理一个内部计数器,该计数器由每个 acquire() 调用递减,并由每个 release() 调用递增。 计数器永远不会低于零; 当 acquire() 发现它为零时,它会阻塞,直到某个任务调用 release()

可选的 value 参数给出内部计数器的初始值(默认为 1)。 如果给定值小于 0,则会引发 ValueError

使用信号量的首选方法是 async with 语句:

sem = asyncio.Semaphore(10)

# ... later
async with sem:
    # work with shared resource

这相当于:

sem = asyncio.Semaphore(10)

# ... later
await sem.acquire()
try:
    # work with shared resource
finally:
    sem.release()
locked()

如果不能立即获取信号量,则返回 True

release()

释放信号量,将内部计数器加一。 可以唤醒一个等待获取信号量的任务。

BoundedSemaphore 不同,Semaphore 允许进行比 acquire() 调用更多的 release() 调用。


有界信号量

class asyncio.BoundedSemaphore(value=1, \*, loop=None)

有界信号量对象。 不是线程安全的。

有界信号量是 Semaphore 的一个版本,如果将内部计数器增加到初始 以上,则会在 release() 中引发 ValueError



3.9 版更改:使用 await lockyield from lock 和/或 with 语句获取锁(with await lockwith (yield from lock)) 被移除。 请改用 async with lock