“Python/docs/3.9/library/threading”的版本间差异

来自菜鸟教程
Python/docs/3.9/library/threading
跳转至:导航、​搜索
(autoload)
 
(Page commit)
 
第1行: 第1行:
 +
{{DISPLAYTITLE:线程 — 基于线程的并行 — Python 文档}}
 
<div id="module-threading" class="section">
 
<div id="module-threading" class="section">
  
 
<span id="threading-thread-based-parallelism"></span>
 
<span id="threading-thread-based-parallelism"></span>
= [[#module-threading|<code>threading</code>]] --- Thread-based parallelism =
+
= threading — 基于线程的并行性 =
  
'''Source code:''' [https://github.com/python/cpython/tree/3.9/Lib/threading.py Lib/threading.py]
+
'''源代码:''' [[#id1|<span id="id2" class="problematic">:source:`Lib/threading.py`</span>]]
  
This module constructs higher-level threading interfaces on top of the lower
+
 
level [[../_thread#module-_thread|<code>_thread</code>]] module. See also the [[../queue#module-queue|<code>queue</code>]] module.
+
-----
 +
 
 +
该模块在较低级别的 [[../_thread#module-_thread|_thread]] 模块的顶部构造更高级别的线程接口。 另请参阅 [[../queue#module-queue|queue]] 模块。
  
 
<div class="versionchanged">
 
<div class="versionchanged">
  
<span class="versionmodified changed">3.7 版更改: </span>This module used to be optional, it is now always available.
+
<span class="versionmodified changed"> 3.7 版本变更: </span> 该模块以前是可选的,现在一直可用。
  
  
第17行: 第20行:
 
<div class="admonition note">
 
<div class="admonition note">
  
注解
+
笔记
  
While they are not listed below, the <code>camelCase</code> names used for some
+
虽然下面没有列出它们,但该模块仍然支持 Python 2.x 系列中该模块中某些方法和函数使用的 <code>camelCase</code> 名称。
methods and functions in this module in the Python 2.x series are still
 
supported by this module.
 
  
  
 
</div>
 
</div>
This module defines the following functions:
+
该模块定义了以下功能:
  
; <code>threading.</code><code>active_count</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">threading.</span></span><span class="sig-name descname"><span class="pre">active_count</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
: Return the number of [[#threading.Thread|<code>Thread</code>]] objects currently alive. The returned count is equal to the length of the list returned by [[#threading.enumerate|<code>enumerate()</code>]].
+
: 返回当前活动的 [[#threading.Thread|Thread]] 对象的数量。 返回的计数等于 [[#threading.enumerate|enumerate()]] 返回的列表的长度。
  
; <code>threading.</code><code>current_thread</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">threading.</span></span><span class="sig-name descname"><span class="pre">current_thread</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
: Return the current [[#threading.Thread|<code>Thread</code>]] object, corresponding to the caller's thread of control. If the caller's thread of control was not created through the [[#module-threading|<code>threading</code>]] module, a dummy thread object with limited functionality is returned.
+
: 返回当前的 [[#threading.Thread|Thread]] 对象,对应于调用者的控制线程。 如果调用者的控制线程不是通过 [[#module-threading|threading]] 模块创建的,则返回一个功能有限的虚拟线程对象。
  
 
<dl>
 
<dl>
<dt><code>threading.</code><code>excepthook</code><span class="sig-paren">(</span>''<span class="n">args</span>'', ''<span class="o">/</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">threading.</span></span><span class="sig-name descname"><span class="pre">excepthook</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">args</span></span>'', ''<span class="o"><span class="pre">/</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Handle uncaught exception raised by [[#threading.Thread.run|<code>Thread.run()</code>]].</p>
+
<dd><p>处理由 [[#threading.Thread.run|Thread.run()]] 引发的未捕获异常。</p>
<p>The ''args'' argument has the following attributes:</p>
+
<p>''args'' 参数具有以下属性:</p>
 
<ul>
 
<ul>
<li><p>''exc_type'': Exception type.</p></li>
+
<li><p>''exc_type'':异常类型。</p></li>
<li><p>''exc_value'': Exception value, can be <code>None</code>.</p></li>
+
<li><p>''exc_value'':异常值,可以是<code>None</code></p></li>
<li><p>''exc_traceback'': Exception traceback, can be <code>None</code>.</p></li>
+
<li><p>''exc_traceback'':异常回溯,可以是<code>None</code></p></li>
<li><p>''thread'': Thread which raised the exception, can be <code>None</code>.</p></li></ul>
+
<li><p>''thread'':引发异常的线程,可以是<code>None</code></p></li></ul>
  
<p>If ''exc_type'' is [[../exceptions#SystemExit|<code>SystemExit</code>]], the exception is silently ignored.
+
<p>如果 ''exc_type'' [[../exceptions#SystemExit|SystemExit]],异常会被静默忽略。 否则,异常会打印在 [[../sys#sys|sys.stderr]] 上。</p>
Otherwise, the exception is printed out on [[../sys#sys|<code>sys.stderr</code>]].</p>
+
<p>如果此函数引发异常,则会调用 [[../sys#sys|sys.excepthook()]] 来处理它。</p>
<p>If this function raises an exception, [[../sys#sys|<code>sys.excepthook()</code>]] is called to
+
<p>[[#threading.excepthook|threading.excepthook()]] 可以被覆盖以控制如何处理 [[#threading.Thread.run|Thread.run()]] 引发的未捕获异常。</p>
handle it.</p>
+
<p>使用自定义钩子存储 ''exc_value'' 可以创建引用循环。 当不再需要异常时,应该明确清除它以中断引用循环。</p>
<p>[[#threading.excepthook|<code>threading.excepthook()</code>]] can be overridden to control how uncaught
+
<p>如果将 ''thread 设置为正在完成的对象,则使用自定义钩子存储 thread'' 可以使其复活。 避免在自定义钩子完成后存储 ''thread'' 以避免复活对象。</p>
exceptions raised by [[#threading.Thread.run|<code>Thread.run()</code>]] are handled.</p>
 
<p>Storing ''exc_value'' using a custom hook can create a reference cycle. It
 
should be cleared explicitly to break the reference cycle when the
 
exception is no longer needed.</p>
 
<p>Storing ''thread'' using a custom hook can resurrect it if it is set to an
 
object which is being finalized. Avoid storing ''thread'' after the custom
 
hook completes to avoid resurrecting objects.</p>
 
 
<div class="admonition seealso">
 
<div class="admonition seealso">
  
<p>参见</p>
+
<p>也可以看看</p>
<p>[[../sys#sys|<code>sys.excepthook()</code>]] handles uncaught exceptions.</p>
+
<p>[[../sys#sys|sys.excepthook()]] 处理未捕获的异常。</p>
  
 
</div>
 
</div>
 
<div class="versionadded">
 
<div class="versionadded">
  
<p><span class="versionmodified added">3.8 新版功能.</span></p>
+
<p><span class="versionmodified added">3.8 版中的新功能。</span></p>
  
 
</div></dd></dl>
 
</div></dd></dl>
  
 
<dl>
 
<dl>
<dt><code>threading.</code><code>get_ident</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">threading.</span></span><span class="sig-name descname"><span class="pre">get_ident</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Return the 'thread identifier' of the current thread. This is a nonzero
+
<dd><p>返回当前线程的“线程标识符”。 这是一个非零整数。 它的价值没有直接的意义; 它旨在用作魔术饼干,例如 索引线程特定数据的字典。 当一个线程退出并创建另一个线程时,线程标识符可能会被回收。</p>
integer. Its value has no direct meaning; it is intended as a magic cookie
 
to be used e.g. to index a dictionary of thread-specific data. Thread
 
identifiers may be recycled when a thread exits and another thread is
 
created.</p>
 
 
<div class="versionadded">
 
<div class="versionadded">
  
<p><span class="versionmodified added">3.3 新版功能.</span></p>
+
<p><span class="versionmodified added">3.3 版中的新功能。</span></p>
  
 
</div></dd></dl>
 
</div></dd></dl>
  
 
<dl>
 
<dl>
<dt><code>threading.</code><code>get_native_id</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">threading.</span></span><span class="sig-name descname"><span class="pre">get_native_id</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Return the native integral Thread ID of the current thread assigned by the kernel.
+
<dd><p>返回内核分配的当前线程的本机整数线程 ID。 这是一个非负整数。 它的值可用于在系统范围内唯一标识此特定线程(直到线程终止,之后该值可由操作系统回收)。</p>
This is a non-negative integer.
 
Its value may be used to uniquely identify this particular thread system-wide
 
(until the thread terminates, after which the value may be recycled by the OS).</p>
 
<p>[[../intro#availability|<span class="std std-ref">Availability</span>]]: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX.</p>
 
 
<div class="versionadded">
 
<div class="versionadded">
  
<p><span class="versionmodified added">3.8 新版功能.</span></p>
+
<p><span class="versionmodified added">3.8 版中的新功能。</span></p>
  
 
</div></dd></dl>
 
</div></dd></dl>
  
; <code>threading.</code><code>enumerate</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">threading.</span></span><span class="sig-name descname"><span class="pre">enumerate</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
: Return a list of all [[#threading.Thread|<code>Thread</code>]] objects currently alive. The list includes daemonic threads, dummy thread objects created by [[#threading.current_thread|<code>current_thread()</code>]], and the main thread. It excludes terminated threads and threads that have not yet been started.
+
: 返回当前活动的所有 [[#threading.Thread|Thread]] 对象的列表。 该列表包括由 [[#threading.current_thread|current_thread()]] 创建的守护线程和虚拟线程对象。 它不包括终止的线程和尚未启动的线程。 但是,主线程始终是结果的一部分,即使在终止时也是如此。
  
 
<dl>
 
<dl>
<dt><code>threading.</code><code>main_thread</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">threading.</span></span><span class="sig-name descname"><span class="pre">main_thread</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Return the main [[#threading.Thread|<code>Thread</code>]] object. In normal conditions, the
+
<dd><p>返回主要的 [[#threading.Thread|Thread]] 对象。 在正常情况下,主线程是启动 Python 解释器的线程。</p>
main thread is the thread from which the Python interpreter was
 
started.</p>
 
 
<div class="versionadded">
 
<div class="versionadded">
  
<p><span class="versionmodified added">3.4 新版功能.</span></p>
+
<p><span class="versionmodified added">3.4 版中的新功能。</span></p>
  
 
</div></dd></dl>
 
</div></dd></dl>
  
; <code>threading.</code><code>settrace</code><span class="sig-paren">(</span>''<span class="n">func</span>''<span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">threading.</span></span><span class="sig-name descname"><span class="pre">settrace</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">func</span></span>''<span class="sig-paren">)</span>
: Set a trace function for all threads started from the [[#module-threading|<code>threading</code>]] module. The ''func'' will be passed to [[../sys#sys|<code>sys.settrace()</code>]] for each thread, before its [[#threading.Thread.run|<code>run()</code>]] method is called.
+
: 为从 [[#module-threading|threading]] 模块启动的所有线程设置跟踪函数。 ''func'' 将在每个线程的 [[#threading.Thread.run|run()]] 方法被调用之前传递给 [[../sys#sys|sys.settrace()]]
  
; <code>threading.</code><code>setprofile</code><span class="sig-paren">(</span>''<span class="n">func</span>''<span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">threading.</span></span><span class="sig-name descname"><span class="pre">setprofile</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">func</span></span>''<span class="sig-paren">)</span>
: Set a profile function for all threads started from the [[#module-threading|<code>threading</code>]] module. The ''func'' will be passed to [[../sys#sys|<code>sys.setprofile()</code>]] for each thread, before its [[#threading.Thread.run|<code>run()</code>]] method is called.
+
: 为从 [[#module-threading|threading]] 模块启动的所有线程设置配置文件函数。 ''func'' 将在每个线程的 [[#threading.Thread.run|run()]] 方法被调用之前传递给 [[../sys#sys|sys.setprofile()]]
  
<dl>
+
; <span class="sig-prename descclassname"><span class="pre">threading.</span></span><span class="sig-name descname"><span class="pre">stack_size</span></span><span class="sig-paren">(</span><span class="optional">[</span>''<span class="pre">size</span>''<span class="optional">]</span><span class="sig-paren">)</span>
<dt><code>threading.</code><code>stack_size</code><span class="sig-paren">(</span><span class="optional">[</span>''size''<span class="optional">]</span><span class="sig-paren">)</span></dt>
+
: 返回创建新线程时使用的线程堆栈大小。 可选的 ''size'' 参数指定用于后续创建的线程的堆栈大小,并且必须为 0(使用平台或配置的默认值)或至少为 32,768 (32 KiB) 的正整数值。 如果未指定 ''size'',则使用 0。 如果不支持更改线程堆栈大小,则会引发 [[../exceptions#RuntimeError|RuntimeError]]。 如果指定的堆栈大小无效,则会引发 [[../exceptions#ValueError|ValueError]] 并且堆栈大小未修改。 32 KiB 目前是支持的最小堆栈大小值,以保证解释器本身有足够的堆栈空间。 请注意,某些平台可能对堆栈大小的值有特定限制,例如要求最小堆栈大小 &gt; 32 KiB 或要求以系统内存页面大小的倍数进行分配 - 应参考平台文档以获取更多信息(4 KiB 页很常见;如果没有更具体的信息,建议使用 4096 的倍数作为堆栈大小)。
<dd><p>Return the thread stack size used when creating new threads. The optional
 
''size'' argument specifies the stack size to be used for subsequently created
 
threads, and must be 0 (use platform or configured default) or a positive
 
integer value of at least 32,768 (32 KiB). If ''size'' is not specified,
 
0 is used. If changing the thread stack size is
 
unsupported, a [[../exceptions#RuntimeError|<code>RuntimeError</code>]] is raised. If the specified stack size is
 
invalid, a [[../exceptions#ValueError|<code>ValueError</code>]] is raised and the stack size is unmodified. 32 KiB
 
is currently the minimum supported stack size value to guarantee sufficient
 
stack space for the interpreter itself. Note that some platforms may have
 
particular restrictions on values for the stack size, such as requiring a
 
minimum stack size &gt; 32 KiB or requiring allocation in multiples of the system
 
memory page size - platform documentation should be referred to for more
 
information (4 KiB pages are common; using multiples of 4096 for the stack size is
 
the suggested approach in the absence of more specific information).</p>
 
<p>[[../intro#availability|<span class="std std-ref">Availability</span>]]: Windows, systems with POSIX threads.</p></dd></dl>
 
  
This module also defines the following constant:
+
该模块还定义了以下常量:
  
 
<dl>
 
<dl>
<dt><code>threading.</code><code>TIMEOUT_MAX</code></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">threading.</span></span><span class="sig-name descname"><span class="pre">TIMEOUT_MAX</span></span></dt>
<dd><p>The maximum value allowed for the ''timeout'' parameter of blocking functions
+
<dd><p>阻塞函数的 ''timeout'' 参数允许的最大值 ([[#threading.Lock.acquire|Lock.acquire()]], [[#threading.RLock.acquire|RLock.acquire()]], [[#threading.Condition.wait|Condition.wait()]] 等)。 指定大于此值的超时将引发 [[../exceptions#OverflowError|OverflowError]]</p>
([[#threading.Lock.acquire|<code>Lock.acquire()</code>]], [[#threading.RLock.acquire|<code>RLock.acquire()</code>]], [[#threading.Condition.wait|<code>Condition.wait()</code>]], etc.).
 
Specifying a timeout greater than this value will raise an
 
[[../exceptions#OverflowError|<code>OverflowError</code>]].</p>
 
 
<div class="versionadded">
 
<div class="versionadded">
  
<p><span class="versionmodified added">3.2 新版功能.</span></p>
+
<p><span class="versionmodified added">3.2 版中的新功能。</span></p>
  
 
</div></dd></dl>
 
</div></dd></dl>
  
This module defines a number of classes, which are detailed in the sections
+
该模块定义了许多类,在下面的部分中进行了详细说明。
below.
 
  
The design of this module is loosely based on Java's threading model. However,
+
该模块的设计松散地基于 Java 的线程模型。 然而,Java 使锁和条件变量成为每个对象的基本行为,它们在 Python 中是独立的对象。 Python [[#threading.Thread|Thread]] 类支持 Java Thread 类的行为子集; 目前,没有优先级,没有线程组,线程不能被销毁、停止、暂停、恢复或中断。 Java Thread 类的静态方法在实现时被映射到模块级函数。
where Java makes locks and condition variables basic behavior of every object,
 
they are separate objects in Python. Python's [[#threading.Thread|<code>Thread</code>]] class supports a
 
subset of the behavior of Java's Thread class; currently, there are no
 
priorities, no thread groups, and threads cannot be destroyed, stopped,
 
suspended, resumed, or interrupted. The static methods of Java's Thread class,
 
when implemented, are mapped to module-level functions.
 
  
All of the methods described below are executed atomically.
+
下面描述的所有方法都是以原子方式执行的。
  
 
<div id="thread-local-data" class="section">
 
<div id="thread-local-data" class="section">
  
== Thread-Local Data ==
+
== 线程本地数据 ==
  
Thread-local data is data whose values are thread specific. To manage
+
线程本地数据是其值是线程特定的数据。 要管理线程本地数据,只需创建 [[#threading.local|local]](或子类)的实例并在其上存储属性:
thread-local data, just create an instance of [[#threading.local|<code>local</code>]] (or a
 
subclass) and store attributes on it:
 
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第170行: 第127行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>mydata = threading.local()
+
<syntaxhighlight lang="python3">mydata = threading.local()
mydata.x = 1</pre>
+
mydata.x = 1</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
The instance's values will be different for separate threads.
+
对于不同的线程,实例的值会有所不同。
  
 
<dl>
 
<dl>
<dt>''class'' <code>threading.</code><code>local</code></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">threading.</span></span><span class="sig-name descname"><span class="pre">local</span></span></dt>
<dd><p>A class that represents thread-local data.</p>
+
<dd><p>表示线程本地数据的类。</p>
<p>For more details and extensive examples, see the documentation string of the
+
<p>有关更多详细信息和大量示例,请参阅 <code>_threading_local</code> 模块的文档字符串。</p></dd></dl>
<code>_threading_local</code> module.</p></dd></dl>
 
  
  
第188行: 第144行:
 
<div id="thread-objects" class="section">
 
<div id="thread-objects" class="section">
  
<span id="id1"></span>
+
<span id="id3"></span>
== Thread Objects ==
+
== 线程对象 ==
  
The [[#threading.Thread|<code>Thread</code>]] class represents an activity that is run in a separate
+
[[#threading.Thread|Thread]] 类表示在单独的控制线程中运行的活动。 有两种方法可以指定活动:通过将可调用对象传递给构造函数,或通过覆盖子类中的 [[#threading.Thread.run|run()]] 方法。 不应在子类中覆盖其他方法(构造函数除外)。 换句话说,''only'' 覆盖了这个类的 <code>__init__()</code> [[#threading.Thread.run|run()]] 方法。
thread of control. There are two ways to specify the activity: by passing a
 
callable object to the constructor, or by overriding the [[#threading.Thread.run|<code>run()</code>]]
 
method in a subclass. No other methods (except for the constructor) should be
 
overridden in a subclass. In other words, ''only'' override the
 
<code>__init__()</code> and [[#threading.Thread.run|<code>run()</code>]] methods of this class.
 
  
Once a thread object is created, its activity must be started by calling the
+
创建线程对象后,必须通过调用线程的 [[#threading.Thread.start|start()]] 方法启动其活动。 这会在单独的控制线程中调用 [[#threading.Thread.run|run()]] 方法。
thread's [[#threading.Thread.start|<code>start()</code>]] method. This invokes the [[#threading.Thread.run|<code>run()</code>]]
 
method in a separate thread of control.
 
  
Once the thread's activity is started, the thread is considered 'alive'. It
+
一旦线程的活动开始,线程就被认为是“活动的”。 当它的 [[#threading.Thread.run|run()]] 方法终止时,它停止活动——正常情况下,或者通过引发未处理的异常。 [[#threading.Thread.is_alive|is_alive()]] 方法测试线程是否处于活动状态。
stops being alive when its [[#threading.Thread.run|<code>run()</code>]] method terminates -- either
 
normally, or by raising an unhandled exception. The [[#threading.Thread.is_alive|<code>is_alive()</code>]]
 
method tests whether the thread is alive.
 
  
Other threads can call a thread's [[#threading.Thread.join|<code>join()</code>]] method. This blocks
+
其他线程可以调用线程的 [[#threading.Thread.join|join()]] 方法。 这会阻塞调用线程,直到调用其 [[#threading.Thread.join|join()]] 方法的线程终止。
the calling thread until the thread whose [[#threading.Thread.join|<code>join()</code>]] method is
 
called is terminated.
 
  
A thread has a name. The name can be passed to the constructor, and read or
+
一个线程有一个名字。 名称可以传递给构造函数,并通过 [[#threading.Thread.name|name]] 属性读取或更改。
changed through the [[#threading.Thread.name|<code>name</code>]] attribute.
 
  
If the [[#threading.Thread.run|<code>run()</code>]] method raises an exception,
+
如果 [[#threading.Thread.run|run()]] 方法引发异常,则会调用 [[#threading.excepthook|threading.excepthook()]] 来处理它。 默认情况下,[[#threading.excepthook|threading.excepthook()]] 静默忽略 [[../exceptions#SystemExit|SystemExit]]
[[#threading.excepthook|<code>threading.excepthook()</code>]] is called to handle it. By default,
 
[[#threading.excepthook|<code>threading.excepthook()</code>]] ignores silently [[../exceptions#SystemExit|<code>SystemExit</code>]].
 
  
A thread can be flagged as a &quot;daemon thread&quot;. The significance of this flag is
+
一个线程可以被标记为“守护线程”。 这个标志的意义在于,当只剩下守护线程时,整个 Python 程序就会退出。 初始值是从创建线程继承的。 该标志可以通过 [[#threading.Thread.daemon|daemon]] 属性或 ''daemon'' 构造函数参数设置。
that the entire Python program exits when only daemon threads are left. The
 
initial value is inherited from the creating thread. The flag can be set
 
through the [[#threading.Thread.daemon|<code>daemon</code>]] property or the ''daemon'' constructor
 
argument.
 
  
 
<div class="admonition note">
 
<div class="admonition note">
  
注解
+
笔记
  
Daemon threads are abruptly stopped at shutdown. Their resources (such
+
守护线程在关机时突然停止。 他们的资源(如打开的文件、数据库事务等)可能无法正常释放。 如果您希望您的线程正常停止,请将它们设为非守护进程并使用合适的信号机制,例如 [[#threading.Event|Event]]
as open files, database transactions, etc.) may not be released properly.
 
If you want your threads to stop gracefully, make them non-daemonic and
 
use a suitable signalling mechanism such as an [[#threading.Event|<code>Event</code>]].
 
  
  
 
</div>
 
</div>
There is a &quot;main thread&quot; object; this corresponds to the initial thread of
+
有一个“主线程”对象; 这对应于 Python 程序中的初始控制线程。 它不是守护线程。
control in the Python program. It is not a daemon thread.
 
  
There is the possibility that &quot;dummy thread objects&quot; are created. These are
+
有可能创建“虚拟线程对象”。 这些是与“外来线程”相对应的线程对象,它们是在线程模块之外启动的控制线程,例如直接从 C 代码启动。 虚拟线程对象的功能有限; 它们总是被认为是活着的和守护进程,并且不能被 [[#threading.Thread.join|join()]]ed。 它们永远不会被删除,因为不可能检测到外来线程的终止。
thread objects corresponding to &quot;alien threads&quot;, which are threads of control
 
started outside the threading module, such as directly from C code. Dummy
 
thread objects have limited functionality; they are always considered alive and
 
daemonic, and cannot be [[#threading.Thread.join|<code>join()</code>]]ed. They are never deleted,
 
since it is impossible to detect the termination of alien threads.
 
  
 
<dl>
 
<dl>
<dt>''class'' <code>threading.</code><code>Thread</code><span class="sig-paren">(</span>''<span class="n">group</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="n">target</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="n">name</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="n">args</span><span class="o">=</span><span class="default_value">()</span>'', ''<span class="n">kwargs</span><span class="o">=</span><span class="default_value">{}</span>'', ''<span class="o">*</span>'', ''<span class="n">daemon</span><span class="o">=</span><span class="default_value">None</span>''<span class="sig-paren">)</span></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">threading.</span></span><span class="sig-name descname"><span class="pre">Thread</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">group</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="n"><span class="pre">target</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="n"><span class="pre">name</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="n"><span class="pre">args</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">()</span></span>'', ''<span class="n"><span class="pre">kwargs</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">{}</span></span>'', ''<span class="o"><span class="pre">*</span></span>'', ''<span class="n"><span class="pre">daemon</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>This constructor should always be called with keyword arguments. Arguments
+
<dd><p>应始终使用关键字参数调用此构造函数。 参数是:</p>
are:</p>
+
<p>''''应为<code>None</code>; 为将来实现 <code>ThreadGroup</code> 类时的扩展保留。</p>
<p>''group'' should be <code>None</code>; reserved for future extension when a
+
<p>''target'' 是由 [[#threading.Thread.run|run()]] 方法调用的可调用对象。 默认为 <code>None</code>,意味着什么都不调用。</p>
<code>ThreadGroup</code> class is implemented.</p>
+
<p>''name'' 是线程名称。 默认情况下,唯一名称的构造形式为“Thread-''N''”,其中 ''N'' 是一个小十进制数。</p>
<p>''target'' is the callable object to be invoked by the [[#threading.Thread.run|<code>run()</code>]] method.
+
<p>''args'' 是目标调用的参数元组。 默认为 <code>()</code></p>
Defaults to <code>None</code>, meaning nothing is called.</p>
+
<p>''kwargs'' 是目标调用的关键字参数字典。 默认为 <code>{}</code></p>
<p>''name'' is the thread name. By default, a unique name is constructed of the
+
<p>如果不是 <code>None</code>,则 ''daemon'' 明确设置线程是否是守护进程。 如果是 <code>None</code>(默认值),守护进程属性是从当前线程继承的。</p>
form &quot;Thread-''N''&quot; where ''N'' is a small decimal number.</p>
+
<p>如果子类覆盖了构造函数,它必须确保在对线程执行任何其他操作之前调用基类构造函数 (<code>Thread.__init__()</code>)</p>
<p>''args'' is the argument tuple for the target invocation. Defaults to <code>()</code>.</p>
 
<p>''kwargs'' is a dictionary of keyword arguments for the target invocation.
 
Defaults to <code>{}</code>.</p>
 
<p>If not <code>None</code>, ''daemon'' explicitly sets whether the thread is daemonic.
 
If <code>None</code> (the default), the daemonic property is inherited from the
 
current thread.</p>
 
<p>If the subclass overrides the constructor, it must make sure to invoke the
 
base class constructor (<code>Thread.__init__()</code>) before doing anything else to
 
the thread.</p>
 
 
<div class="versionchanged">
 
<div class="versionchanged">
  
<p><span class="versionmodified changed">在 3.3 版更改: </span>Added the ''daemon'' argument.</p>
+
<p><span class="versionmodified changed"> 在 3.3 版更改: </span> 添加了 ''守护进程'' 参数。</p>
  
 
</div>
 
</div>
 
<dl>
 
<dl>
<dt><code>start</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">start</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Start the thread's activity.</p>
+
<dd><p>启动线程的活动。</p>
<p>It must be called at most once per thread object. It arranges for the
+
<p>每个线程对象最多必须调用一次。 它安排在单独的控制线程中调用对象的 [[#threading.Thread.run|run()]] 方法。</p>
object's [[#threading.Thread.run|<code>run()</code>]] method to be invoked in a separate thread
+
<p>如果在同一个线程对象上多次调用此方法,则会引发 [[../exceptions#RuntimeError|RuntimeError]]</p></dd></dl>
of control.</p>
 
<p>This method will raise a [[../exceptions#RuntimeError|<code>RuntimeError</code>]] if called more than once
 
on the same thread object.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>run</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">run</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Method representing the thread's activity.</p>
+
<dd><p>表示线程活动的方法。</p>
<p>You may override this method in a subclass. The standard [[#threading.Thread.run|<code>run()</code>]]
+
<p>您可以在子类中覆盖此方法。 标准的 [[#threading.Thread.run|run()]] 方法调用传递给对象构造函数的可调用对象作为 ''target'' 参数,如果有的话,位置和关键字参数取自 ''args''''kwargs'' 参数,分别。</p></dd></dl>
method invokes the callable object passed to the object's constructor as
 
the ''target'' argument, if any, with positional and keyword arguments taken
 
from the ''args'' and ''kwargs'' arguments, respectively.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>join</code><span class="sig-paren">(</span>''<span class="n">timeout</span><span class="o">=</span><span class="default_value">None</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">join</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Wait until the thread terminates. This blocks the calling thread until
+
<dd><p>等待线程终止。 这会阻塞调用线程,直到调用其 [[#threading.Thread.join|join()]] 方法的线程终止 - 通常或通过未处理的异常 - 或直到发生可选超时。</p>
the thread whose [[#threading.Thread.join|<code>join()</code>]] method is called terminates -- either
+
<p>''timeout'' 参数存在而不是 <code>None</code> 时,它应该是一个浮点数,以秒(或其分数)为单位指定操作超时。 由于 [[#threading.Thread.join|join()]] 总是返回 <code>None</code>,你必须在 [[#threading.Thread.join|join()]] 之后调用 [[#threading.Thread.is_alive|is_alive()]] 来决定是否发生超时 - 如果线程仍然存在,[[#threading.Thread.join|join()]] 调用超时。</p>
normally or through an unhandled exception -- or until the optional
+
<p>''timeout'' 参数不存在或 <code>None</code> 时,操作将阻塞,直到线程终止。</p>
timeout occurs.</p>
+
<p>一个线程可以被 [[#threading.Thread.join|join()]]ed 多次。</p>
<p>When the ''timeout'' argument is present and not <code>None</code>, it should be a
+
<p>[[#threading.Thread.join|join()]] 如果尝试加入当前线程,则会引发 [[../exceptions#RuntimeError|RuntimeError]],因为这会导致死锁。 在线程启动之前 [[#threading.Thread.join|join()]] 线程也是一个错误,并且尝试这样做会引发相同的异常。</p></dd></dl>
floating point number specifying a timeout for the operation in seconds
 
(or fractions thereof). As [[#threading.Thread.join|<code>join()</code>]] always returns <code>None</code>,
 
you must call [[#threading.Thread.is_alive|<code>is_alive()</code>]] after [[#threading.Thread.join|<code>join()</code>]] to
 
decide whether a timeout happened -- if the thread is still alive, the
 
[[#threading.Thread.join|<code>join()</code>]] call timed out.</p>
 
<p>When the ''timeout'' argument is not present or <code>None</code>, the operation will
 
block until the thread terminates.</p>
 
<p>A thread can be [[#threading.Thread.join|<code>join()</code>]]ed many times.</p>
 
<p>[[#threading.Thread.join|<code>join()</code>]] raises a [[../exceptions#RuntimeError|<code>RuntimeError</code>]] if an attempt is made
 
to join the current thread as that would cause a deadlock. It is also
 
an error to [[#threading.Thread.join|<code>join()</code>]] a thread before it has been started
 
and attempts to do so raise the same exception.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>name</code></dt>
+
<dt><span class="sig-name descname"><span class="pre">name</span></span></dt>
<dd><p>A string used for identification purposes only. It has no semantics.
+
<dd><p>仅用于识别目的的字符串。 它没有语义。 多个线程可能会被赋予相同的名称。 初始名称由构造函数设置。</p></dd></dl>
Multiple threads may be given the same name. The initial name is set by
 
the constructor.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>getName</code><span class="sig-paren">(</span><span class="sig-paren">)</span><br />
+
<dt><span class="sig-name descname"><span class="pre">getName</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><br />
<code>setName</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<span class="sig-name descname"><span class="pre">setName</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Old getter/setter API for [[#threading.Thread.name|<code>name</code>]]; use it directly as a
+
<dd><p>[[#threading.Thread.name|name]] 的旧 getter/setter API; 直接将其用作属性。</p></dd></dl>
property instead.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>ident</code></dt>
+
<dt><span class="sig-name descname"><span class="pre">ident</span></span></dt>
<dd><p>The 'thread identifier' of this thread or <code>None</code> if the thread has not
+
<dd><p>此线程的“线程标识符”或 <code>None</code>(如果该线程尚未启动)。 这是一个非零整数。 请参阅 [[#threading.get_ident|get_ident()]] 函数。 当一个线程退出并创建另一个线程时,线程标识符可能会被回收。 即使在线程退出后,标识符仍然可用。</p></dd></dl>
been started. This is a nonzero integer. See the [[#threading.get_ident|<code>get_ident()</code>]]
 
function. Thread identifiers may be recycled when a thread exits and
 
another thread is created. The identifier is available even after the
 
thread has exited.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>native_id</code></dt>
+
<dt><span class="sig-name descname"><span class="pre">native_id</span></span></dt>
<dd><p>The native integral thread ID of this thread.
+
<dd><p>此线程的本机完整线程 ID。 这是一个非负整数,如果线程尚未启动,则为 <code>None</code>。 请参阅 [[#threading.get_native_id|get_native_id()]] 函数。 这表示由操作系统(内核)分配给线程的线程 ID (<code>TID</code>)。 它的值可用于在系统范围内唯一标识此特定线程(直到线程终止,之后该值可由操作系统回收)。</p>
This is a non-negative integer, or <code>None</code> if the thread has not
 
been started. See the [[#threading.get_native_id|<code>get_native_id()</code>]] function.
 
This represents the Thread ID (<code>TID</code>) as assigned to the
 
thread by the OS (kernel). Its value may be used to uniquely identify
 
this particular thread system-wide (until the thread terminates,
 
after which the value may be recycled by the OS).</p>
 
 
<div class="admonition note">
 
<div class="admonition note">
  
<p>注解</p>
+
<p>笔记</p>
<p>Similar to Process IDs, Thread IDs are only valid (guaranteed unique
+
<p>与进程 ID 类似,线程 ID 仅从创建线程到线程终止期间有效(保证在系统范围内唯一)。</p>
system-wide) from the time the thread is created until the thread
 
has been terminated.</p>
 
  
 
</div>
 
</div>
<p>[[../intro#availability|<span class="std std-ref">Availability</span>]]: Requires [[#threading.get_native_id|<code>get_native_id()</code>]] function.</p>
 
 
<div class="versionadded">
 
<div class="versionadded">
  
<p><span class="versionmodified added">3.8 新版功能.</span></p>
+
<p><span class="versionmodified added">3.8 版中的新功能。</span></p>
  
 
</div></dd></dl>
 
</div></dd></dl>
  
 
<dl>
 
<dl>
<dt><code>is_alive</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">is_alive</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Return whether the thread is alive.</p>
+
<dd><p>返回线程是否存活。</p>
<p>This method returns <code>True</code> just before the [[#threading.Thread.run|<code>run()</code>]] method
+
<p>该方法在 [[#threading.Thread.run|run()]] 方法开始之前返回 <code>True</code>,直到 [[#threading.Thread.run|run()]] 方法终止之后。 模块函数 [[#threading.enumerate|enumerate()]] 返回所有活动线程的列表。</p></dd></dl>
starts until just after the [[#threading.Thread.run|<code>run()</code>]] method terminates. The
 
module function [[#threading.enumerate|<code>enumerate()</code>]] returns a list of all alive threads.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>daemon</code></dt>
+
<dt><span class="sig-name descname"><span class="pre">daemon</span></span></dt>
<dd><p>A boolean value indicating whether this thread is a daemon thread (True)
+
<dd><p>一个布尔值,指示此线程是否为守护线程 (True) 或不是 (False)。 这必须在调用 [[#threading.Thread.start|start()]] 之前设置,否则会引发 [[../exceptions#RuntimeError|RuntimeError]]。 它的初始值是从创建线程继承的; 主线程不是守护线程,因此在主线程中创建的所有线程默认为 [[#threading.Thread.daemon|daemon]] = <code>False</code></p>
or not (False). This must be set before [[#threading.Thread.start|<code>start()</code>]] is called,
+
<p>当没有存活的非守护线程时,整个 Python 程序就会退出。</p></dd></dl>
otherwise [[../exceptions#RuntimeError|<code>RuntimeError</code>]] is raised. Its initial value is inherited
 
from the creating thread; the main thread is not a daemon thread and
 
therefore all threads created in the main thread default to
 
[[#threading.Thread.daemon|<code>daemon</code>]] = <code>False</code>.</p>
 
<p>The entire Python program exits when no alive non-daemon threads are left.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>isDaemon</code><span class="sig-paren">(</span><span class="sig-paren">)</span><br />
+
<dt><span class="sig-name descname"><span class="pre">isDaemon</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><br />
<code>setDaemon</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<span class="sig-name descname"><span class="pre">setDaemon</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Old getter/setter API for [[#threading.Thread.daemon|<code>daemon</code>]]; use it directly as a
+
<dd><p>[[#threading.Thread.daemon|daemon]] 的旧 getter/setter API; 直接将其用作属性。</p></dd></dl>
property instead.</p></dd></dl>
 
 
</dd></dl>
 
</dd></dl>
 
<div class="impl-detail compound">
 
 
'''CPython implementation detail:''' In CPython, due to the [[../../glossary#term-global-interpreter-lock|<span class="xref std std-term">Global Interpreter Lock</span>]], only one thread
 
can execute Python code at once (even though certain performance-oriented
 
libraries might overcome this limitation).
 
If you want your application to make better use of the computational
 
resources of multi-core machines, you are advised to use
 
[[../multiprocessing#module-multiprocessing|<code>multiprocessing</code>]] or [[../concurrent.futures#concurrent.futures|<code>concurrent.futures.ProcessPoolExecutor</code>]].
 
However, threading is still an appropriate model if you want to run
 
multiple I/O-bound tasks simultaneously.
 
  
 
</div>
 
  
 
</div>
 
</div>
 
<div id="lock-objects" class="section">
 
<div id="lock-objects" class="section">
  
<span id="id2"></span>
+
<span id="id4"></span>
== Lock Objects ==
+
== 锁定对象 ==
  
A primitive lock is a synchronization primitive that is not owned by a
+
原语锁是一种同步原语,锁定时不属于特定线程。 在 Python 中,它是目前可用的最低级同步原语,由 [[../_thread#module-_thread|_thread]] 扩展模块直接实现。
particular thread when locked. In Python, it is currently the lowest level
 
synchronization primitive available, implemented directly by the [[../_thread#module-_thread|<code>_thread</code>]]
 
extension module.
 
  
A primitive lock is in one of two states, &quot;locked&quot; or &quot;unlocked&quot;. It is created
+
原始锁处于“锁定”或“解锁”两种状态之一。 它是在解锁状态下创建的。 它有两个基本方法,[[#threading.Lock.acquire|acquire()]] [[#threading.Lock.release|release()]]。 当状态解锁时, [[#threading.Lock.acquire|acquire()]] 将状态更改为锁定并立即返回。 当状态被锁定时,[[#threading.Lock.acquire|acquire()]] 阻塞,直到另一个线程中对 [[#threading.Lock.release|release()]] 的调用将其更改为解锁,然后 [[#threading.Lock.acquire|acquire()]] 调用重置它锁定并返回。 [[#threading.Lock.release|release()]] 方法只能在锁定状态下调用; 它将状态更改为解锁并立即返回。 如果尝试释放未锁定的锁,则会引发 [[../exceptions#RuntimeError|RuntimeError]]
in the unlocked state. It has two basic methods, [[#threading.Lock.acquire|<code>acquire()</code>]] and
 
[[#threading.Lock.release|<code>release()</code>]]. When the state is unlocked, [[#threading.Lock.acquire|<code>acquire()</code>]]
 
changes the state to locked and returns immediately. When the state is locked,
 
[[#threading.Lock.acquire|<code>acquire()</code>]] blocks until a call to [[#threading.Lock.release|<code>release()</code>]] in another
 
thread changes it to unlocked, then the [[#threading.Lock.acquire|<code>acquire()</code>]] call resets it
 
to locked and returns. The [[#threading.Lock.release|<code>release()</code>]] method should only be
 
called in the locked state; it changes the state to unlocked and returns
 
immediately. If an attempt is made to release an unlocked lock, a
 
[[../exceptions#RuntimeError|<code>RuntimeError</code>]] will be raised.
 
  
Locks also support the [[#with-locks|<span class="std std-ref">context management protocol</span>]].
+
锁还支持 [[#with-locks|上下文管理协议]]
  
When more than one thread is blocked in [[#threading.Lock.acquire|<code>acquire()</code>]] waiting for the
+
[[#threading.Lock.acquire|acquire()]]中多个线程被阻塞等待状态变为unlocked时,当[[#threading.Lock.release|release()]]调用将状态重置为unlocked时,只有一个线程继续执行; 未定义等待线程中的哪一个进行,并且可能因实现而异。
state to turn to unlocked, only one thread proceeds when a [[#threading.Lock.release|<code>release()</code>]]
 
call resets the state to unlocked; which one of the waiting threads proceeds
 
is not defined, and may vary across implementations.
 
  
All methods are executed atomically.
+
所有方法都是原子执行的。
  
 
<dl>
 
<dl>
<dt>''class'' <code>threading.</code><code>Lock</code></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">threading.</span></span><span class="sig-name descname"><span class="pre">Lock</span></span></dt>
<dd><p>The class implementing primitive lock objects. Once a thread has acquired a
+
<dd><p>实现原始锁对象的类。 一旦一个线程获得了一个锁,后续的获得它的尝试就会阻塞,直到它被释放; 任何线程都可以释放它。</p>
lock, subsequent attempts to acquire it block, until it is released; any
+
<p>请注意, <code>Lock</code> 实际上是一个工厂函数,它返回平台支持的具体 Lock 类的最有效版本的实例。</p>
thread may release it.</p>
 
<p>Note that <code>Lock</code> is actually a factory function which returns an instance
 
of the most efficient version of the concrete Lock class that is supported
 
by the platform.</p>
 
 
<dl>
 
<dl>
<dt><code>acquire</code><span class="sig-paren">(</span>''<span class="n">blocking</span><span class="o">=</span><span class="default_value">True</span>'', ''<span class="n">timeout</span><span class="o">=</span><span class="default_value">- 1</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">acquire</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">blocking</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">True</span></span>'', ''<span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">-</span> <span class="pre">1</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Acquire a lock, blocking or non-blocking.</p>
+
<dd><p>获取锁,阻塞或非阻塞。</p>
<p>When invoked with the ''blocking'' argument set to <code>True</code> (the default),
+
<p>当调用 ''blocking'' 参数设置为 <code>True</code>(默认值)时,阻塞直到锁被解锁,然后将其设置为锁定并返回 <code>True</code></p>
block until the lock is unlocked, then set it to locked and return <code>True</code>.</p>
+
<p>当调用 ''blocking'' 参数设置为 <code>False</code> 时,不要阻塞。 如果 ''blocking'' 设置为 <code>True</code> 的调用会阻塞,则立即返回 <code>False</code>; 否则,设置锁为locked并返回<code>True</code></p>
<p>When invoked with the ''blocking'' argument set to <code>False</code>, do not block.
+
<p>在将浮点 ''timeout'' 参数设置为正值的情况下调用时,最多阻塞 ''timeout'' 指定的秒数,并且只要无法获取锁。 <code>-1</code> ''timeout'' 参数指定无限等待。 当 ''blocking'' false 时,禁止指定 ''timeout''。</p>
If a call with ''blocking'' set to <code>True</code> would block, return <code>False</code>
+
<p>如果成功获取锁,则返回值为 <code>True</code>,否则返回值为 <code>False</code>(例如,如果 ''timeout'' 已过期)。</p>
immediately; otherwise, set the lock to locked and return <code>True</code>.</p>
 
<p>When invoked with the floating-point ''timeout'' argument set to a positive
 
value, block for at most the number of seconds specified by ''timeout''
 
and as long as the lock cannot be acquired. A ''timeout'' argument of <code>-1</code>
 
specifies an unbounded wait. It is forbidden to specify a ''timeout''
 
when ''blocking'' is false.</p>
 
<p>The return value is <code>True</code> if the lock is acquired successfully,
 
<code>False</code> if not (for example if the ''timeout'' expired).</p>
 
 
<div class="versionchanged">
 
<div class="versionchanged">
  
<p><span class="versionmodified changed">3.2 版更改: </span>The ''timeout'' parameter is new.</p>
+
<p><span class="versionmodified changed"> 3.2 版更改: </span> ''timeout'' 参数是新的。</p>
  
 
</div>
 
</div>
 
<div class="versionchanged">
 
<div class="versionchanged">
  
<p><span class="versionmodified changed">3.2 版更改: </span>Lock acquisition can now be interrupted by signals on POSIX if the
+
<p><span class="versionmodified changed"> 3.2 版更改: </span> 如果底层线程实现支持,现在可以被 POSIX 上的信号中断获取锁。</p>
underlying threading implementation supports it.</p>
 
  
 
</div></dd></dl>
 
</div></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 lock. This can be called from any thread, not only the thread
+
<dd><p>释放锁。 这可以从任何线程调用,而不仅仅是获取锁的线程。</p>
which has acquired the lock.</p>
+
<p>当锁被锁定时,将其重置为解锁,然后返回。 如果任何其他线程在等待锁定解锁时被阻塞,则只允许其中一个线程继续执行。</p>
<p>When the lock is locked, reset it to unlocked, and return. If any other threads
+
<p>当在解锁的锁上调用时,会引发 [[../exceptions#RuntimeError|RuntimeError]]</p>
are blocked waiting for the lock to become unlocked, allow exactly one of them
+
<p>没有返回值。</p></dd></dl>
to proceed.</p>
 
<p>When invoked on an unlocked lock, a [[../exceptions#RuntimeError|<code>RuntimeError</code>]] is raised.</p>
 
<p>There is no return value.</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 true if the lock is acquired.</p></dd></dl>
+
<dd><p>如果获得了锁,则返回 true。</p></dd></dl>
 
</dd></dl>
 
</dd></dl>
  
第473行: 第306行:
 
<div id="rlock-objects" class="section">
 
<div id="rlock-objects" class="section">
  
<span id="id3"></span>
+
<span id="id5"></span>
== RLock Objects ==
+
== RLock 对象 ==
  
A reentrant lock is a synchronization primitive that may be acquired multiple
+
重入锁是一个同步原语,可以被同一个线程多次获取。 在内部,除了原始锁使用的锁定/解锁状态之外,它还使用“拥有线程”和“递归级别”的概念。 在锁定状态下,某个线程拥有锁; 在解锁状态下,没有线程拥有它。
times by the same thread. Internally, it uses the concepts of &quot;owning thread&quot;
 
and &quot;recursion level&quot; in addition to the locked/unlocked state used by primitive
 
locks. In the locked state, some thread owns the lock; in the unlocked state,
 
no thread owns it.
 
  
To lock the lock, a thread calls its [[#threading.RLock.acquire|<code>acquire()</code>]] method; this
+
为了锁定锁,线程调用其 [[#threading.RLock.acquire|acquire()]] 方法; 一旦线程拥有锁,它就会返回。 要解锁锁,线程调用其 [[#threading.Lock.release|release()]] 方法。 [[#threading.Lock.acquire|acquire()]]/[[#threading.Lock.release|release()]] 调用对可以嵌套; 只有最后的 [[#threading.Lock.release|release()]](最外面对的 [[#threading.Lock.release|release()]])将锁重置为解锁状态,并允许在 [[#threading.Lock.acquire|acquire()]] 中阻塞的另一个线程继续进行.
returns once the thread owns the lock. To unlock the lock, a thread calls
 
its [[#threading.Lock.release|<code>release()</code>]] method. [[#threading.Lock.acquire|<code>acquire()</code>]]/[[#threading.Lock.release|<code>release()</code>]]
 
call pairs may be nested; only the final [[#threading.Lock.release|<code>release()</code>]] (the
 
[[#threading.Lock.release|<code>release()</code>]] of the outermost pair) resets the lock to unlocked and
 
allows another thread blocked in [[#threading.Lock.acquire|<code>acquire()</code>]] to proceed.
 
  
Reentrant locks also support the [[#with-locks|<span class="std std-ref">context management protocol</span>]].
+
可重入锁还支持 [X33X] 上下文管理协议 。
  
 
<dl>
 
<dl>
<dt>''class'' <code>threading.</code><code>RLock</code></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">threading.</span></span><span class="sig-name descname"><span class="pre">RLock</span></span></dt>
<dd><p>This class implements reentrant lock objects. A reentrant lock must be
+
<dd><p>此类实现可重入锁对象。 重入锁必须由获取它的线程释放。 一旦一个线程获得了可重入锁,同一个线程就可以再次获得它而不会阻塞; 线程每次获得它时都必须释放一次。</p>
released by the thread that acquired it. Once a thread has acquired a
+
<p>请注意,<code>RLock</code> 实际上是一个工厂函数,它返回平台支持的具体 RLock 类的最有效版本的实例。</p>
reentrant lock, the same thread may acquire it again without blocking; the
 
thread must release it once for each time it has acquired it.</p>
 
<p>Note that <code>RLock</code> is actually a factory function which returns an instance
 
of the most efficient version of the concrete RLock class that is supported
 
by the platform.</p>
 
 
<dl>
 
<dl>
<dt><code>acquire</code><span class="sig-paren">(</span>''<span class="n">blocking</span><span class="o">=</span><span class="default_value">True</span>'', ''<span class="n">timeout</span><span class="o">=</span><span class="default_value">- 1</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">acquire</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">blocking</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">True</span></span>'', ''<span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">-</span> <span class="pre">1</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Acquire a lock, blocking or non-blocking.</p>
+
<dd><p>获取锁,阻塞或非阻塞。</p>
<p>When invoked without arguments: if this thread already owns the lock, increment
+
<p>不带参数调用时:如果此线程已拥有锁,则将递归级别增加 1,并立即返回。 否则,如果另一个线程拥有锁,则阻塞直到锁被解锁。 一旦锁被解锁(不属于任何线程),然后获取所有权,将递归级别设置为 1,然后返回。 如果有多个线程在等待锁被解锁之前被阻塞,则一次只有一个线程能够获取锁的所有权。 在这种情况下没有返回值。</p>
the recursion level by one, and return immediately. Otherwise, if another
+
<p>''blocking'' 参数设置为 true 的情况下调用时,执行与不带参数调用时相同的操作,并返回 <code>True</code></p>
thread owns the lock, block until the lock is unlocked. Once the lock is
+
<p>当在 ''blocking'' 参数设置为 false 的情况下调用时,不要阻塞。 如果没有参数的调用会阻塞,立即返回 <code>False</code>; 否则,执行与不带参数调用时相同的操作,并返回 <code>True</code></p>
unlocked (not owned by any thread), then grab ownership, set the recursion level
+
<p>在将浮点 ''timeout'' 参数设置为正值的情况下调用时,最多阻塞 ''timeout'' 指定的秒数,并且只要无法获取锁。 如果已获取锁,则返回 <code>True</code>,如果超时已过,则返回 false。</p>
to one, and return. If more than one thread is blocked waiting until the lock
 
is unlocked, only one at a time will be able to grab ownership of the lock.
 
There is no return value in this case.</p>
 
<p>When invoked with the ''blocking'' argument set to true, do the same thing as when
 
called without arguments, and return <code>True</code>.</p>
 
<p>When invoked with the ''blocking'' argument set to false, do not block. If a call
 
without an argument would block, return <code>False</code> immediately; otherwise, do the
 
same thing as when called without arguments, and return <code>True</code>.</p>
 
<p>When invoked with the floating-point ''timeout'' argument set to a positive
 
value, block for at most the number of seconds specified by ''timeout''
 
and as long as the lock cannot be acquired. Return <code>True</code> if the lock has
 
been acquired, false if the timeout has elapsed.</p>
 
 
<div class="versionchanged">
 
<div class="versionchanged">
  
<p><span class="versionmodified changed">3.2 版更改: </span>The ''timeout'' parameter is new.</p>
+
<p><span class="versionmodified changed"> 3.2 版更改: </span> ''timeout'' 参数是新的。</p>
  
 
</div></dd></dl>
 
</div></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 lock, decrementing the recursion level. If after the decrement it is
+
<dd><p>释放锁,递减递归级别。 如果递减后它为零,则将锁重置为解锁(不属于任何线程),并且如果任何其他线程被阻塞等待锁解锁,则只允许其中一个线程继续进行。 如果递减后递归级别仍然不为零,则锁保持锁定并由调用线程拥有。</p>
zero, reset the lock to unlocked (not owned by any thread), and if any other
+
<p>仅当调用线程拥有锁时才调用此方法。 如果在解锁时调用此方法,则会引发 [[../exceptions#RuntimeError|RuntimeError]]</p>
threads are blocked waiting for the lock to become unlocked, allow exactly one
+
<p>没有返回值。</p></dd></dl>
of them to proceed. If after the decrement the recursion level is still
 
nonzero, the lock remains locked and owned by the calling thread.</p>
 
<p>Only call this method when the calling thread owns the lock. A
 
[[../exceptions#RuntimeError|<code>RuntimeError</code>]] is raised if this method is called when the lock is
 
unlocked.</p>
 
<p>There is no return value.</p></dd></dl>
 
 
</dd></dl>
 
</dd></dl>
  
第542行: 第343行:
 
<div id="condition-objects" class="section">
 
<div id="condition-objects" class="section">
  
<span id="id4"></span>
+
<span id="id6"></span>
== Condition Objects ==
+
== 条件对象 ==
  
A condition variable is always associated with some kind of lock; this can be
+
条件变量总是与某种锁相关联; 这可以传入或默认创建一个。 当多个条件变量必须共享同一个锁时,传入一个很有用。 锁是条件对象的一部分:您不必单独跟踪它。
passed in or one will be created by default. Passing one in is useful when
 
several condition variables must share the same lock. The lock is part of
 
the condition object: you don't have to track it separately.
 
  
A condition variable obeys the [[#with-locks|<span class="std std-ref">context management protocol</span>]]:
+
条件变量遵循 [[#with-locks|上下文管理协议]] :使用 <code>with</code> 语句在封闭块的持续时间内获取关联的锁。 [[#threading.Condition.acquire|acquire()]] [[#threading.Condition.release|release()]] 方法也调用了关联锁的对应方法。
using the <code>with</code> statement acquires the associated lock for the duration of
 
the enclosed block. The [[#threading.Condition.acquire|<code>acquire()</code>]] and
 
[[#threading.Condition.release|<code>release()</code>]] methods also call the corresponding methods of
 
the associated lock.
 
  
Other methods must be called with the associated lock held. The
+
必须在持有相关锁的情况下调用其他方法。 [[#threading.Condition.wait|wait()]] 方法释放锁,然后阻塞,直到另一个线程通过调用 [[#threading.Condition.notify|notify()]] [[#threading.Condition.notify_all|notify_all()]] 唤醒它。 一旦被唤醒,[[#threading.Condition.wait|wait()]] 重新获取锁并返回。 也可以指定超时。
[[#threading.Condition.wait|<code>wait()</code>]] method releases the lock, and then blocks until
 
another thread awakens it by calling [[#threading.Condition.notify|<code>notify()</code>]] or
 
[[#threading.Condition.notify_all|<code>notify_all()</code>]]. Once awakened, [[#threading.Condition.wait|<code>wait()</code>]]
 
re-acquires the lock and returns. It is also possible to specify a timeout.
 
  
The [[#threading.Condition.notify|<code>notify()</code>]] method wakes up one of the threads waiting for
+
[[#threading.Condition.notify|notify()]] 方法唤醒等待条件变量的线程之一(如果有任何等待)。 [[#threading.Condition.notify_all|notify_all()]] 方法唤醒所有等待条件变量的线程。
the condition variable, if any are waiting. The [[#threading.Condition.notify_all|<code>notify_all()</code>]]
 
method wakes up all threads waiting for the condition variable.
 
  
Note: the [[#threading.Condition.notify|<code>notify()</code>]] and [[#threading.Condition.notify_all|<code>notify_all()</code>]] methods
+
注意:[[#threading.Condition.notify|notify()]] [[#threading.Condition.notify_all|notify_all()]] 方法不会释放锁; 这意味着被唤醒的线程不会立即从它们的 [[#threading.Condition.wait|wait()]] 调用中返回,而是只有在调用 [[#threading.Condition.notify|notify()]] [[#threading.Condition.notify_all|notify_all()]] 的线程时才返回] 最后放弃锁的所有权。
don't release the lock; this means that the thread or threads awakened will
 
not return from their [[#threading.Condition.wait|<code>wait()</code>]] call immediately, but only when
 
the thread that called [[#threading.Condition.notify|<code>notify()</code>]] or [[#threading.Condition.notify_all|<code>notify_all()</code>]]
 
finally relinquishes ownership of the lock.
 
  
The typical programming style using condition variables uses the lock to
+
使用条件变量的典型编程风格使用锁来同步对某些共享状态的访问; 对特定状态更改感兴趣的线程重复调用 [[#threading.Condition.wait|wait()]] 直到他们看到所需的状态,而修改状态的线程调用 [[#threading.Condition.notify|notify()]] [[#threading.Condition.notify_all|notify_all( )]] 当他们以这样一种方式改变状态时,它可能是其中一个服务员想要的状态。 例如,以下代码是具有无限缓冲区容量的通用生产者-消费者情况:
synchronize access to some shared state; threads that are interested in a
 
particular change of state call [[#threading.Condition.wait|<code>wait()</code>]] repeatedly until they
 
see the desired state, while threads that modify the state call
 
[[#threading.Condition.notify|<code>notify()</code>]] or [[#threading.Condition.notify_all|<code>notify_all()</code>]] when they change
 
the state in such a way that it could possibly be a desired state for one
 
of the waiters. For example, the following code is a generic
 
producer-consumer situation with unlimited buffer capacity:
 
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第585行: 第362行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre># Consume one item
+
<syntaxhighlight lang="python3"># Consume one item
 
with cv:
 
with cv:
 
     while not an_item_is_available():
 
     while not an_item_is_available():
第594行: 第371行:
 
with cv:
 
with cv:
 
     make_an_item_available()
 
     make_an_item_available()
     cv.notify()</pre>
+
     cv.notify()</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
The <code>while</code> loop checking for the application's condition is necessary
+
<code>while</code> 循环检查应用程序的条件是必要的,因为 [[#threading.Condition.wait|wait()]] 可以在任意长时间后返回,并且提示 [[#threading.Condition.notify|notify()]] 调用的条件可能不再成立。 这是多线程编程所固有的。 [[#threading.Condition.wait_for|wait_for()]] 方法可用于自动进行条件检查,并简化超时计算:
because [[#threading.Condition.wait|<code>wait()</code>]] can return after an arbitrary long time,
 
and the condition which prompted the [[#threading.Condition.notify|<code>notify()</code>]] call may
 
no longer hold true. This is inherent to multi-threaded programming. The
 
[[#threading.Condition.wait_for|<code>wait_for()</code>]] method can be used to automate the condition
 
checking, and eases the computation of timeouts:
 
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第610行: 第382行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre># Consume an item
+
<syntaxhighlight lang="python3"># Consume an item
 
with cv:
 
with cv:
 
     cv.wait_for(an_item_is_available)
 
     cv.wait_for(an_item_is_available)
     get_an_available_item()</pre>
+
     get_an_available_item()</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
To choose between [[#threading.Condition.notify|<code>notify()</code>]] and [[#threading.Condition.notify_all|<code>notify_all()</code>]],
+
要在 [[#threading.Condition.notify|notify()]] [[#threading.Condition.notify_all|notify_all()]] 之间进行选择,请考虑一种状态更改是否只对一个或多个等待线程感兴趣。 例如 在典型的生产者-消费者情况下,将一项添加到缓冲区只需要唤醒一个消费者线程。
consider whether one state change can be interesting for only one or several
 
waiting threads. E.g. in a typical producer-consumer situation, adding one
 
item to the buffer only needs to wake up one consumer thread.
 
  
 
<dl>
 
<dl>
<dt>''class'' <code>threading.</code><code>Condition</code><span class="sig-paren">(</span>''<span class="n">lock</span><span class="o">=</span><span class="default_value">None</span>''<span class="sig-paren">)</span></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">threading.</span></span><span class="sig-name descname"><span class="pre">Condition</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">lock</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>This class implements condition variable objects. A condition variable
+
<dd><p>此类实现条件变量对象。 条件变量允许一个或多个线程等待,直到它们被另一个线程通知。</p>
allows one or more threads to wait until they are notified by another thread.</p>
+
<p>如果给出了 ''lock'' 参数而不是 <code>None</code>,则它必须是 [[#threading.Lock|Lock]] [[#threading.RLock|RLock]] 对象,并用作底层锁. 否则,将创建一个新的 [[#threading.RLock|RLock]] 对象并将其用作底层锁。</p>
<p>If the ''lock'' argument is given and not <code>None</code>, it must be a [[#threading.Lock|<code>Lock</code>]]
 
or [[#threading.RLock|<code>RLock</code>]] object, and it is used as the underlying lock. Otherwise,
 
a new [[#threading.RLock|<code>RLock</code>]] object is created and used as the underlying lock.</p>
 
 
<div class="versionchanged">
 
<div class="versionchanged">
  
<p><span class="versionmodified changed">3.3 版更改: </span>changed from a factory function to a class.</p>
+
<p><span class="versionmodified changed"> 3.3 版更改: </span> 从工厂函数更改为类。</p>
  
 
</div>
 
</div>
 
<dl>
 
<dl>
<dt><code>acquire</code><span class="sig-paren">(</span>''<span class="o">*</span><span class="n">args</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">acquire</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">args</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Acquire the underlying lock. This method calls the corresponding method on
+
<dd><p>获取底层锁。 该方法调用底层锁上的相应方法; 返回值是该方法返回的任何值。</p></dd></dl>
the underlying lock; the return value is whatever that method returns.</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 the underlying lock. This method calls the corresponding method on
+
<dd><p>释放底层锁。 该方法调用底层锁上的相应方法; 没有返回值。</p></dd></dl>
the underlying lock; there is no return value.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>wait</code><span class="sig-paren">(</span>''<span class="n">timeout</span><span class="o">=</span><span class="default_value">None</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">wait</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Wait until notified or until a timeout occurs. If the calling thread has
+
<dd><p>等到通知或直到发生超时。 如果调用此方法时调用线程尚未获取锁,则会引发 [[../exceptions#RuntimeError|RuntimeError]]</p>
not acquired the lock when this method is called, a [[../exceptions#RuntimeError|<code>RuntimeError</code>]] is
+
<p>此方法释放底层锁,然后阻塞直到它被另一个线程中的相同条件变量的 [[#threading.Condition.notify|notify()]] [[#threading.Condition.notify_all|notify_all()]] 调用唤醒,或者直到可选超时发生。 一旦被唤醒或超时,它会重新获取锁并返回。</p>
raised.</p>
+
<p>''timeout'' 参数存在而不是 <code>None</code> 时,它应该是一个浮点数,以秒(或其分数)为单位指定操作超时。</p>
<p>This method releases the underlying lock, and then blocks until it is
+
<p>当底层锁是 [[#threading.RLock|RLock]] 时,它不会使用其 [[#threading.Condition.release|release()]] 方法释放,因为当它被多次递归获取时,这可能实际上不会解锁锁。 取而代之的是,使用了 [[#threading.RLock|RLock]] 类的内部接口,即使在多次递归获取时,它也能真正解锁它。 然后使用另一个内部接口在重新获取锁时恢复递归级别。</p>
awakened by a [[#threading.Condition.notify|<code>notify()</code>]] or [[#threading.Condition.notify_all|<code>notify_all()</code>]] call for the same
+
<p>返回值是 <code>True</code>,除非给定的 ''timeout'' 过期,在这种情况下它是 <code>False</code></p>
condition variable in another thread, or until the optional timeout
 
occurs. Once awakened or timed out, it re-acquires the lock and returns.</p>
 
<p>When the ''timeout'' argument is present and not <code>None</code>, it should be a
 
floating point number specifying a timeout for the operation in seconds
 
(or fractions thereof).</p>
 
<p>When the underlying lock is an [[#threading.RLock|<code>RLock</code>]], it is not released using
 
its [[#threading.Condition.release|<code>release()</code>]] method, since this may not actually unlock the lock
 
when it was acquired multiple times recursively. Instead, an internal
 
interface of the [[#threading.RLock|<code>RLock</code>]] class is used, which really unlocks it
 
even when it has been recursively acquired several times. Another internal
 
interface is then used to restore the recursion level when the lock is
 
reacquired.</p>
 
<p>The return value is <code>True</code> unless a given ''timeout'' expired, in which
 
case it is <code>False</code>.</p>
 
 
<div class="versionchanged">
 
<div class="versionchanged">
  
<p><span class="versionmodified changed">3.2 版更改: </span>Previously, the method always returned <code>None</code>.</p>
+
<p><span class="versionmodified changed"> 3.2 版本更改: </span> 以前,该方法总是返回 <code>None</code></p>
  
 
</div></dd></dl>
 
</div></dd></dl>
  
 
<dl>
 
<dl>
<dt><code>wait_for</code><span class="sig-paren">(</span>''<span class="n">predicate</span>'', ''<span class="n">timeout</span><span class="o">=</span><span class="default_value">None</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">wait_for</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">predicate</span></span>'', ''<span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Wait until a condition evaluates to true. ''predicate'' should be a
+
<dd><p>等到条件评估为真。 ''predicate'' 应该是一个可调用的结果将被解释为一个布尔值。 可以提供一个 ''timeout'',给出最长的等待时间。</p>
callable which result will be interpreted as a boolean value.
+
<p>这个实用方法可能会重复调用 [[#threading.Condition.wait|wait()]] 直到满足谓词,或者直到发生超时。 返回值是谓词的最后一个返回值,如果方法超时,它将评估为 <code>False</code></p>
A ''timeout'' may be provided giving the maximum time to wait.</p>
+
<p>忽略超时特性,调用这个方法大致相当于写:</p>
<p>This utility method may call [[#threading.Condition.wait|<code>wait()</code>]] repeatedly until the predicate
 
is satisfied, or until a timeout occurs. The return value is
 
the last return value of the predicate and will evaluate to
 
<code>False</code> if the method timed out.</p>
 
<p>Ignoring the timeout feature, calling this method is roughly equivalent to
 
writing:</p>
 
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>while not predicate():
+
<syntaxhighlight lang="python3">while not predicate():
     cv.wait()</pre>
+
     cv.wait()</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
<p>Therefore, the same rules apply as with [[#threading.Condition.wait|<code>wait()</code>]]: The lock must be
+
<p>因此,应用与 [[#threading.Condition.wait|wait()]] 相同的规则:调用时必须持有锁,并在返回时重新获取。 谓词在持有锁的情况下进行评估。</p>
held when called and is re-acquired on return. The predicate is evaluated
 
with the lock held.</p>
 
 
<div class="versionadded">
 
<div class="versionadded">
  
<p><span class="versionmodified added">3.2 新版功能.</span></p>
+
<p><span class="versionmodified added">3.2 版中的新功能。</span></p>
  
 
</div></dd></dl>
 
</div></dd></dl>
  
 
<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>
+
<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>By default, wake up one thread waiting on this condition, if any. If the
+
<dd><p>默认情况下,唤醒一个等待此条件的线程(如果有)。 如果调用此方法时调用线程尚未获取锁,则会引发 [[../exceptions#RuntimeError|RuntimeError]]</p>
calling thread has not acquired the lock when this method is called, a
+
<p>该方法最多唤醒''n''个等待条件变量的线程; 如果没有线程在等待,则为空操作。</p>
[[../exceptions#RuntimeError|<code>RuntimeError</code>]] is raised.</p>
+
<p>如果至少有 ''n'' 个线程在等待,当前实现会准确唤醒 ''n'' 个线程。 但是,依赖这种行为是不安全的。 未来的优化实现可能偶尔会唤醒超过 ''n'' 个线程。</p>
<p>This method wakes up at most ''n'' of the threads waiting for the condition
+
<p>注意:被唤醒的线程实际上不会从它的 [[#threading.Condition.wait|wait()]] 调用中返回,直到它可以重新获取锁。 由于 [[#threading.Condition.notify|notify()]] 不释放锁,它的调用者应该。</p></dd></dl>
variable; it is a no-op if no threads are waiting.</p>
 
<p>The current implementation wakes up exactly ''n'' threads, if at least ''n''
 
threads are waiting. However, it's not safe to rely on this behavior.
 
A future, optimized implementation may occasionally wake up more than
 
''n'' threads.</p>
 
<p>Note: an awakened thread does not actually return from its [[#threading.Condition.wait|<code>wait()</code>]]
 
call until it can reacquire the lock. Since [[#threading.Condition.notify|<code>notify()</code>]] does not
 
release the lock, its caller should.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>notify_all</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>Wake up all threads waiting on this condition. This method acts like
+
<dd><p>唤醒所有在此条件下等待的线程。 此方法的作用类似于 [[#threading.Condition.notify|notify()]],但唤醒所有等待线程而不是一个。 如果调用此方法时调用线程尚未获取锁,则会引发 [[../exceptions#RuntimeError|RuntimeError]]</p></dd></dl>
[[#threading.Condition.notify|<code>notify()</code>]], but wakes up all waiting threads instead of one. If the
 
calling thread has not acquired the lock when this method is called, a
 
[[../exceptions#RuntimeError|<code>RuntimeError</code>]] is raised.</p></dd></dl>
 
 
</dd></dl>
 
</dd></dl>
  
第729行: 第460行:
 
<div id="semaphore-objects" class="section">
 
<div id="semaphore-objects" class="section">
  
<span id="id5"></span>
+
<span id="id7"></span>
== Semaphore Objects ==
+
== 信号量对象 ==
  
This is one of the oldest synchronization primitives in the history of computer
+
这是计算机科学史上最古老的同步原语之一,由早期的荷兰计算机科学家 Edsger W. Dijkstra(他使用名称 <code>P()</code> <code>V()</code> 而不是 [[#threading.Semaphore.acquire|acquire()]] [[#threading.Semaphore.release|release()]])。
science, invented by the early Dutch computer scientist Edsger W. Dijkstra (he
 
used the names <code>P()</code> and <code>V()</code> instead of [[#threading.Semaphore.acquire|<code>acquire()</code>]] and
 
[[#threading.Semaphore.release|<code>release()</code>]]).
 
  
A semaphore manages an internal counter which is decremented by each
+
信号量管理一个内部计数器,该计数器由每个 [[#threading.Semaphore.acquire|acquire()]] 调用递减,并由每个 [[#threading.Semaphore.release|release()]] 调用递增。 计数器永远不会低于零; 当 [[#threading.Semaphore.acquire|acquire()]] 发现它为零时,它会阻塞,等待其他线程调用 [[#threading.Semaphore.release|release()]]
[[#threading.Semaphore.acquire|<code>acquire()</code>]] call and incremented by each [[#threading.Semaphore.release|<code>release()</code>]]
 
call. The counter can never go below zero; when [[#threading.Semaphore.acquire|<code>acquire()</code>]]
 
finds that it is zero, it blocks, waiting until some other thread calls
 
[[#threading.Semaphore.release|<code>release()</code>]].
 
  
Semaphores also support the [[#with-locks|<span class="std std-ref">context management protocol</span>]].
+
信号量还支持 [[#with-locks|上下文管理协议]]
  
 
<dl>
 
<dl>
<dt>''class'' <code>threading.</code><code>Semaphore</code><span class="sig-paren">(</span>''<span class="n">value</span><span class="o">=</span><span class="default_value">1</span>''<span class="sig-paren">)</span></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">threading.</span></span><span class="sig-name descname"><span class="pre">Semaphore</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">value</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>This class implements semaphore objects. A semaphore manages an atomic
+
<dd><p>这个类实现了信号量对象。 信号量管理一个原子计数器,表示 [[#threading.Semaphore.release|release()]] 调用的数量减去 [[#threading.Semaphore.acquire|acquire()]] 调用的数量,再加上一个初始值。 [[#threading.Semaphore.acquire|acquire()]] 方法在必要时阻塞,直到它可以在不使计数器为负的情况下返回。 如果没有给出,''value'' 默认为 1。</p>
counter representing the number of [[#threading.Semaphore.release|<code>release()</code>]] calls minus the number of
+
<p>可选参数给出内部计数器的初始 '''' ; 默认为 <code>1</code>。 如果给定的 '''' 小于 0,则会引发 [[../exceptions#ValueError|ValueError]]</p>
[[#threading.Semaphore.acquire|<code>acquire()</code>]] calls, plus an initial value. The [[#threading.Semaphore.acquire|<code>acquire()</code>]] method
 
blocks if necessary until it can return without making the counter negative.
 
If not given, ''value'' defaults to 1.</p>
 
<p>The optional argument gives the initial ''value'' for the internal counter; it
 
defaults to <code>1</code>. If the ''value'' given is less than 0, [[../exceptions#ValueError|<code>ValueError</code>]] is
 
raised.</p>
 
 
<div class="versionchanged">
 
<div class="versionchanged">
  
<p><span class="versionmodified changed">3.3 版更改: </span>changed from a factory function to a class.</p>
+
<p><span class="versionmodified changed"> 3.3 版更改: </span> 从工厂函数更改为类。</p>
  
 
</div>
 
</div>
 
<dl>
 
<dl>
<dt><code>acquire</code><span class="sig-paren">(</span>''<span class="n">blocking</span><span class="o">=</span><span class="default_value">True</span>'', ''<span class="n">timeout</span><span class="o">=</span><span class="default_value">None</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">acquire</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">blocking</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">True</span></span>'', ''<span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Acquire a semaphore.</p>
+
<dd><p>获取信号量。</p>
<p>When invoked without arguments:</p>
+
<p>不带参数调用时:</p>
 
<ul>
 
<ul>
<li><p>If the internal counter is larger than zero on entry, decrement it by
+
<li><p>如果内部计数器在进入时大于零,则将其减一并立即返回 <code>True</code></p></li>
one and return <code>True</code> immediately.</p></li>
+
<li><p>如果内部计数器在进入时为零,则阻塞直到被调用 [[#threading.Semaphore.release|release()]] 唤醒。 一旦唤醒(并且计数器大于 0),将计数器减 1 并返回 <code>True</code>。 每次调用 [[#threading.Semaphore.release|release()]] 都会唤醒一个线程。 不应依赖线程被唤醒的顺序。</p></li></ul>
<li><p>If the internal counter is zero on entry, block until awoken by a call to
 
[[#threading.Semaphore.release|<code>release()</code>]]. Once awoken (and the counter is greater
 
than 0), decrement the counter by 1 and return <code>True</code>. Exactly one
 
thread will be awoken by each call to [[#threading.Semaphore.release|<code>release()</code>]]. The
 
order in which threads are awoken should not be relied on.</p></li></ul>
 
  
<p>When invoked with ''blocking'' set to false, do not block. If a call
+
<p>当在 ''blocking'' 设置为 false 的情况下调用时,不要阻止。 如果没有参数的调用会阻塞,立即返回 <code>False</code>; 否则,执行与不带参数调用时相同的操作,并返回 <code>True</code></p>
without an argument would block, return <code>False</code> immediately; otherwise, do
+
<p>当使用 <code>None</code> 以外的 ''timeout'' 调用时,它最多会阻塞 ''timeout'' 秒。 如果在该时间间隔内未成功完成获取,则返回 <code>False</code>。 否则返回 <code>True</code></p>
the same thing as when called without arguments, and return <code>True</code>.</p>
 
<p>When invoked with a ''timeout'' other than <code>None</code>, it will block for at
 
most ''timeout'' seconds. If acquire does not complete successfully in
 
that interval, return <code>False</code>. Return <code>True</code> otherwise.</p>
 
 
<div class="versionchanged">
 
<div class="versionchanged">
  
<p><span class="versionmodified changed">3.2 版更改: </span>The ''timeout'' parameter is new.</p>
+
<p><span class="versionmodified changed"> 3.2 版更改: </span> ''timeout'' 参数是新的。</p>
  
 
</div></dd></dl>
 
</div></dd></dl>
  
 
<dl>
 
<dl>
<dt><code>release</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>
+
<dt><span class="sig-name descname"><span class="pre">release</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>Release a semaphore, incrementing the internal counter by ''n''. When it
+
<dd><p>释放信号量,将内部计数器增加 ''n''。 当它在进入时为零并且其他线程正在等待它再次变得大于零时,唤醒这些线程的 ''n''</p>
was zero on entry and other threads are waiting for it to become larger
 
than zero again, wake up ''n'' of those threads.</p>
 
 
<div class="versionchanged">
 
<div class="versionchanged">
  
<p><span class="versionmodified changed">3.9 版更改: </span>Added the ''n'' parameter to release multiple waiting threads at once.</p>
+
<p><span class="versionmodified changed"> 3.9 版更改: </span> 增加了 ''n'' 参数,可以一次性释放多个等待线程。</p>
  
 
</div></dd></dl>
 
</div></dd></dl>
第798行: 第505行:
  
 
<dl>
 
<dl>
<dt>''class'' <code>threading.</code><code>BoundedSemaphore</code><span class="sig-paren">(</span>''<span class="n">value</span><span class="o">=</span><span class="default_value">1</span>''<span class="sig-paren">)</span></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">threading.</span></span><span class="sig-name descname"><span class="pre">BoundedSemaphore</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">value</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>Class implementing bounded semaphore objects. A bounded semaphore checks to
+
<dd><p>实现有界信号量对象的类。 有界信号量检查以确保其当前值不超过其初始值。 如果是,则引发 [[../exceptions#ValueError|ValueError]]。 在大多数情况下,信号量用于保护容量有限的资源。 如果信号量被释放太多次,则表明存在错误。 如果没有给出,''value'' 默认为 1。</p>
make sure its current value doesn't exceed its initial value. If it does,
 
[[../exceptions#ValueError|<code>ValueError</code>]] is raised. In most situations semaphores are used to guard
 
resources with limited capacity. If the semaphore is released too many times
 
it's a sign of a bug. If not given, ''value'' defaults to 1.</p>
 
 
<div class="versionchanged">
 
<div class="versionchanged">
  
<p><span class="versionmodified changed">3.3 版更改: </span>changed from a factory function to a class.</p>
+
<p><span class="versionmodified changed"> 3.3 版更改: </span> 从工厂函数更改为类。</p>
  
 
</div></dd></dl>
 
</div></dd></dl>
第813行: 第516行:
  
 
<span id="semaphore-examples"></span>
 
<span id="semaphore-examples"></span>
=== [[#threading.Semaphore|<code>Semaphore</code>]] Example ===
+
=== 信号量示例 ===
  
Semaphores are often used to guard resources with limited capacity, for example,
+
信号量通常用于保护容量有限的资源,例如数据库服务器。 在资源大小固定的任何情况下,您都应该使用有界信号量。 在产生任何工作线程之前,您的主线程将初始化信号量:
a database server. In any situation where the size of the resource is fixed,
 
you should use a bounded semaphore. Before spawning any worker threads, your
 
main thread would initialize the semaphore:
 
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第824行: 第524行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>maxconnections = 5
+
<syntaxhighlight lang="python3">maxconnections = 5
 
# ...
 
# ...
pool_sema = BoundedSemaphore(value=maxconnections)</pre>
+
pool_sema = BoundedSemaphore(value=maxconnections)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Once spawned, worker threads call the semaphore's acquire and release methods
+
一旦产生,工作线程在需要连接到服务器时调用信号量的获取和释放方法:
when they need to connect to the server:
 
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第838行: 第537行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>with pool_sema:
+
<syntaxhighlight lang="python3">with pool_sema:
 
     conn = connectdb()
 
     conn = connectdb()
 
     try:
 
     try:
 
         # ... use connection ...
 
         # ... use connection ...
 
     finally:
 
     finally:
         conn.close()</pre>
+
         conn.close()</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
The use of a bounded semaphore reduces the chance that a programming error which
+
有界信号量的使用降低了导致信号量释放多于获取量的编程错误未被检测到的可能性。
causes the semaphore to be released more than it's acquired will go undetected.
 
  
  
第857行: 第555行:
 
<div id="event-objects" class="section">
 
<div id="event-objects" class="section">
  
<span id="id6"></span>
+
<span id="id8"></span>
== Event Objects ==
+
== 事件对象 ==
  
This is one of the simplest mechanisms for communication between threads: one
+
这是线程之间最简单的通信机制之一:一个线程发出事件信号,其他线程等待它。
thread signals an event and other threads wait for it.
 
  
An event object manages an internal flag that can be set to true with the
+
事件对象管理一个内部标志,可以使用 [[#threading.Event.set|set()]] 方法将其设置为 true,并使用 [[#threading.Event.clear|clear()]] 方法重置为 false。 [[#threading.Event.wait|wait()]] 方法阻塞,直到标志为真。
[[#threading.Event.set|<code>set()</code>]] method and reset to false with the [[#threading.Event.clear|<code>clear()</code>]]
 
method. The [[#threading.Event.wait|<code>wait()</code>]] method blocks until the flag is true.
 
  
 
<dl>
 
<dl>
<dt>''class'' <code>threading.</code><code>Event</code></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">threading.</span></span><span class="sig-name descname"><span class="pre">Event</span></span></dt>
<dd><p>Class implementing event objects. An event manages a flag that can be set to
+
<dd><p>实现事件对象的类。 事件管理一个标志,该标志可以使用 [[#threading.Event.set|set()]] 方法设置为 true,并使用 [[#threading.Event.clear|clear()]] 方法重置为 false。 [[#threading.Event.wait|wait()]] 方法阻塞,直到标志为真。 该标志最初为假。</p>
true with the [[#threading.Event.set|<code>set()</code>]] method and reset to false with the
 
[[#threading.Event.clear|<code>clear()</code>]] method. The [[#threading.Event.wait|<code>wait()</code>]] method blocks until the flag is true.
 
The flag is initially false.</p>
 
 
<div class="versionchanged">
 
<div class="versionchanged">
  
<p><span class="versionmodified changed">3.3 版更改: </span>changed from a factory function to a class.</p>
+
<p><span class="versionmodified changed"> 3.3 版更改: </span> 从工厂函数更改为类。</p>
  
 
</div>
 
</div>
 
<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 and only if the internal flag is true.</p></dd></dl>
+
<dd><p>当且仅当内部标志为真时返回 <code>True</code></p></dd></dl>
  
 
<dl>
 
<dl>
<dt><code>set</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>Set the internal flag to true. All threads waiting for it to become true
+
<dd><p>将内部标志设置为 true。 所有等待它变为真的线程都被唤醒。 一旦标志为真,调用 [[#threading.Event.wait|wait()]] 的线程根本不会阻塞。</p></dd></dl>
are awakened. Threads that call [[#threading.Event.wait|<code>wait()</code>]] once the flag is true will
 
not block at all.</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>Reset the internal flag to false. Subsequently, threads calling
+
<dd><p>将内部标志重置为 false。 随后,调用 [[#threading.Event.wait|wait()]] 的线程将阻塞,直到调用 [[#threading.Event.set|set()]] 再次将内部标志设置为 true。</p></dd></dl>
[[#threading.Event.wait|<code>wait()</code>]] will block until [[#threading.Event.set|<code>set()</code>]] is called to set the internal
 
flag to true again.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>wait</code><span class="sig-paren">(</span>''<span class="n">timeout</span><span class="o">=</span><span class="default_value">None</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">wait</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Block until the internal flag is true. If the internal flag is true on
+
<dd><p>阻塞直到内部标志为真。 如果内部标志在进入时为真,则立即返回。 否则,阻塞直到另一个线程调用 [[#threading.Event.set|set()]] 将标志设置为 true,或者直到发生可选超时。</p>
entry, return immediately. Otherwise, block until another thread calls
+
<p>timeout 参数存在而不是 <code>None</code> 时,它应该是一个浮点数,以秒(或其分数)为单位指定操作超时。</p>
[[#threading.Event.set|<code>set()</code>]] to set the flag to true, or until the optional timeout occurs.</p>
+
<p>此方法返回 <code>True</code> 当且仅当内部标志已设置为 true 时,无论是在等待调用之前还是等待开始之后,因此它将始终返回 <code>True</code> 除非给出超时并且操作超时。</p>
<p>When the timeout argument is present and not <code>None</code>, it should be a
 
floating point number specifying a timeout for the operation in seconds
 
(or fractions thereof).</p>
 
<p>This method returns <code>True</code> if and only if the internal flag has been set to
 
true, either before the wait call or after the wait starts, so it will
 
always return <code>True</code> except if a timeout is given and the operation
 
times out.</p>
 
 
<div class="versionchanged">
 
<div class="versionchanged">
  
<p><span class="versionmodified changed">3.1 版更改: </span>Previously, the method always returned <code>None</code>.</p>
+
<p><span class="versionmodified changed"> 3.1 更改: </span> 以前,该方法总是返回 <code>None</code></p>
  
 
</div></dd></dl>
 
</div></dd></dl>
第917行: 第598行:
 
<div id="timer-objects" class="section">
 
<div id="timer-objects" class="section">
  
<span id="id7"></span>
+
<span id="id9"></span>
== Timer Objects ==
+
== 定时器对象 ==
  
This class represents an action that should be run only after a certain amount
+
这个类代表一个只有在经过一定时间后才应该运行的动作——一个计时器。 [[#threading.Timer|Timer]] [[#threading.Thread|Thread]] 的子类,因此也可以作为创建自定义线程的示例。
of time has passed --- a timer. [[#threading.Timer|<code>Timer</code>]] is a subclass of [[#threading.Thread|<code>Thread</code>]]
 
and as such also functions as an example of creating custom threads.
 
  
Timers are started, as with threads, by calling their <code>start()</code>
+
定时器与线程一样,通过调用它们的 <code>start()</code> 方法启动。 可以通过调用 [[#threading.Timer.cancel|cancel()]] 方法来停止计时器(在其动作开始之前)。 计时器在执行其操作之前将等待的时间间隔可能与用户指定的时间间隔不完全相同。
method. The timer can be stopped (before its action has begun) by calling the
 
[[#threading.Timer.cancel|<code>cancel()</code>]] method. The interval the timer will wait before
 
executing its action may not be exactly the same as the interval specified by
 
the user.
 
  
For example:
+
例如:
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第936行: 第611行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>def hello():
+
<syntaxhighlight lang="python3">def hello():
     print(&quot;hello, world&quot;)
+
     print("hello, world")
  
 
t = Timer(30.0, hello)
 
t = Timer(30.0, hello)
t.start()  # after 30 seconds, &quot;hello, world&quot; will be printed</pre>
+
t.start()  # after 30 seconds, "hello, world" will be printed</syntaxhighlight>
  
 
</div>
 
</div>
第946行: 第621行:
 
</div>
 
</div>
 
<dl>
 
<dl>
<dt>''class'' <code>threading.</code><code>Timer</code><span class="sig-paren">(</span>''<span class="n">interval</span>'', ''<span class="n">function</span>'', ''<span class="n">args</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="n">kwargs</span><span class="o">=</span><span class="default_value">None</span>''<span class="sig-paren">)</span></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">threading.</span></span><span class="sig-name descname"><span class="pre">Timer</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">interval</span></span>'', ''<span class="n"><span class="pre">function</span></span>'', ''<span class="n"><span class="pre">args</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="n"><span class="pre">kwargs</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Create a timer that will run ''function'' with arguments ''args'' and keyword
+
<dd><p>创建一个计时器,在 ''interval'' 秒过去后,使用参数 ''args'' 和关键字参数 ''kwargs'' 运行 ''function''。 如果 ''args'' <code>None</code>(默认值),则将使用空列表。 如果 ''kwargs'' <code>None</code>(默认值),则将使用空字典。</p>
arguments ''kwargs'', after ''interval'' seconds have passed.
 
If ''args'' is <code>None</code> (the default) then an empty list will be used.
 
If ''kwargs'' is <code>None</code> (the default) then an empty dict will be used.</p>
 
 
<div class="versionchanged">
 
<div class="versionchanged">
  
<p><span class="versionmodified changed">3.3 版更改: </span>changed from a factory function to a class.</p>
+
<p><span class="versionmodified changed"> 3.3 版更改: </span> 从工厂函数更改为类。</p>
  
 
</div>
 
</div>
 
<dl>
 
<dl>
<dt><code>cancel</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">cancel</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Stop the timer, and cancel the execution of the timer's action. This will
+
<dd><p>停止定时器,并取消定时器动作的执行。 这仅在计时器仍处于等待阶段时才有效。</p></dd></dl>
only work if the timer is still in its waiting stage.</p></dd></dl>
 
 
</dd></dl>
 
</dd></dl>
  
第966行: 第637行:
 
<div id="barrier-objects" class="section">
 
<div id="barrier-objects" class="section">
  
== Barrier Objects ==
+
== 障碍物 ==
  
 
<div class="versionadded">
 
<div class="versionadded">
  
<span class="versionmodified added">3.2 新版功能.</span>
+
<span class="versionmodified added">3.2 版中的新功能。</span>
  
  
 
</div>
 
</div>
This class provides a simple synchronization primitive for use by a fixed number
+
此类提供了一个简单的同步原语,供需要相互等待的固定数量的线程使用。 每个线程都试图通过调用 [[#threading.Barrier.wait|wait()]] 方法来通过屏障,并且会一直阻塞,直到所有线程都进行了 [[#threading.Barrier.wait|wait()]] 调用。 此时,线程同时释放。
of threads that need to wait for each other. Each of the threads tries to pass
 
the barrier by calling the [[#threading.Barrier.wait|<code>wait()</code>]] method and will block until
 
all of the threads have made their [[#threading.Barrier.wait|<code>wait()</code>]] calls. At this point,
 
the threads are released simultaneously.
 
  
The barrier can be reused any number of times for the same number of threads.
+
对于相同数量的线程,屏障可以重复使用任意次数。
  
As an example, here is a simple way to synchronize a client and server thread:
+
例如,这里有一个简单的方法来同步客户端和服务器线程:
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第988行: 第655行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>b = Barrier(2, timeout=5)
+
<syntaxhighlight lang="python3">b = Barrier(2, timeout=5)
  
 
def server():
 
def server():
第1,001行: 第668行:
 
     while True:
 
     while True:
 
         connection = make_connection()
 
         connection = make_connection()
         process_client_connection(connection)</pre>
+
         process_client_connection(connection)</syntaxhighlight>
  
 
</div>
 
</div>
第1,007行: 第674行:
 
</div>
 
</div>
 
<dl>
 
<dl>
<dt>''class'' <code>threading.</code><code>Barrier</code><span class="sig-paren">(</span>''<span class="n">parties</span>'', ''<span class="n">action</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="n">timeout</span><span class="o">=</span><span class="default_value">None</span>''<span class="sig-paren">)</span></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">threading.</span></span><span class="sig-name descname"><span class="pre">Barrier</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">parties</span></span>'', ''<span class="n"><span class="pre">action</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Create a barrier object for ''parties'' number of threads. An ''action'', when
+
<dd><p>'''' 个线程创建屏障对象。 ''action'',当提供时,是一个可调用的,当它们被释放时由其中一个线程调用。 ''timeout'' 是默认超时值,如果没有为 [[#threading.Barrier.wait|wait()]] 方法指定。</p>
provided, is a callable to be called by one of the threads when they are
 
released. ''timeout'' is the default timeout value if none is specified for
 
the [[#threading.Barrier.wait|<code>wait()</code>]] method.</p>
 
 
<dl>
 
<dl>
<dt><code>wait</code><span class="sig-paren">(</span>''<span class="n">timeout</span><span class="o">=</span><span class="default_value">None</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">wait</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Pass the barrier. When all the threads party to the barrier have called
+
<dd><p>通过障碍。 当屏障的所有线程都调用了这个函数时,它们都被同时释放。 如果提供了 ''timeout'',则它优先于提供给类构造函数的任何内容使用。</p>
this function, they are all released simultaneously. If a ''timeout'' is
+
<p>返回值是 0 ''party'' 1 范围内的整数,每个线程都不同。 这可以用来选择一个线程来做一些特殊的内务处理,例如:</p>
provided, it is used in preference to any that was supplied to the class
 
constructor.</p>
 
<p>The return value is an integer in the range 0 to ''parties'' -- 1, different
 
for each thread. This can be used to select a thread to do some special
 
housekeeping, e.g.:</p>
 
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>i = barrier.wait()
+
<syntaxhighlight lang="python3">i = barrier.wait()
 
if i == 0:
 
if i == 0:
 
     # Only one thread needs to print this
 
     # Only one thread needs to print this
     print(&quot;passed the barrier&quot;)</pre>
+
     print("passed the barrier")</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
<p>If an ''action'' was provided to the constructor, one of the threads will
+
<p>如果向构造函数提供了 ''action'',其中一个线程将在释放之前调用它。 如果此调用引发错误,则屏障将进入损坏状态。</p>
have called it prior to being released. Should this call raise an error,
+
<p>如果调用超时,屏障将进入破坏状态。</p>
the barrier is put into the broken state.</p>
+
<p>如果在线程等待时屏障被破坏或重置,此方法可能会引发 [[#threading.BrokenBarrierError|BrokenBarrierError]] 异常。</p></dd></dl>
<p>If the call times out, the barrier is put into the broken state.</p>
 
<p>This method may raise a [[#threading.BrokenBarrierError|<code>BrokenBarrierError</code>]] exception if the
 
barrier is broken or reset while a thread is waiting.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>reset</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">reset</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Return the barrier to the default, empty state. Any threads waiting on it
+
<dd><p>将障碍返回到默认的空状态。 任何等待它的线程都会收到 [[#threading.BrokenBarrierError|BrokenBarrierError]] 异常。</p>
will receive the [[#threading.BrokenBarrierError|<code>BrokenBarrierError</code>]] exception.</p>
+
<p>请注意,如果存在状态未知的其他线程,则使用此函数可能需要一些外部同步。 如果障碍被打破,最好离开它并创建一个新的障碍。</p></dd></dl>
<p>Note that using this function may require some external
 
synchronization if there are other threads whose state is unknown. If a
 
barrier is broken it may be better to just leave it and create a new one.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>abort</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">abort</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Put the barrier into a broken state. This causes any active or future
+
<dd><p>将屏障置于破碎状态。 这会导致对 [[#threading.Barrier.wait|wait()]] 的任何活动或未来调用失败,并显示 [[#threading.BrokenBarrierError|BrokenBarrierError]]。 例如,如果其中一个线程需要中止,请使用此选项,以避免死锁应用程序。</p>
calls to [[#threading.Barrier.wait|<code>wait()</code>]] to fail with the [[#threading.BrokenBarrierError|<code>BrokenBarrierError</code>]]. Use
+
<p>最好使用合理的 ''timeout'' 值简单地创建屏障,以自动防止其中一个线程出错。</p></dd></dl>
this for example if one of the threads needs to abort, to avoid deadlocking the
 
application.</p>
 
<p>It may be preferable to simply create the barrier with a sensible
 
''timeout'' value to automatically guard against one of the threads going
 
awry.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>parties</code></dt>
+
<dt><span class="sig-name descname"><span class="pre">parties</span></span></dt>
<dd><p>The number of threads required to pass the barrier.</p></dd></dl>
+
<dd><p>通过屏障所需的线程数。</p></dd></dl>
  
 
<dl>
 
<dl>
<dt><code>n_waiting</code></dt>
+
<dt><span class="sig-name descname"><span class="pre">n_waiting</span></span></dt>
<dd><p>The number of threads currently waiting in the barrier.</p></dd></dl>
+
<dd><p>当前在屏障中等待的线程数。</p></dd></dl>
  
 
<dl>
 
<dl>
<dt><code>broken</code></dt>
+
<dt><span class="sig-name descname"><span class="pre">broken</span></span></dt>
<dd><p>A boolean that is <code>True</code> if the barrier is in the broken state.</p></dd></dl>
+
<dd><p>如果障碍处于损坏状态,则为 <code>True</code> 的布尔值。</p></dd></dl>
 
</dd></dl>
 
</dd></dl>
  
; ''exception'' <code>threading.</code><code>BrokenBarrierError</code>
+
; ''<span class="pre">exception</span>'' <span class="sig-prename descclassname"><span class="pre">threading.</span></span><span class="sig-name descname"><span class="pre">BrokenBarrierError</span></span>
: This exception, a subclass of [[../exceptions#RuntimeError|<code>RuntimeError</code>]], is raised when the [[#threading.Barrier|<code>Barrier</code>]] object is reset or broken.
+
: 这个异常是 [[../exceptions#RuntimeError|RuntimeError]] 的子类,当 [[#threading.Barrier|Barrier]] 对象被重置或损坏时会引发。
  
  
第1,079行: 第727行:
  
 
<span id="with-locks"></span>
 
<span id="with-locks"></span>
== Using locks, conditions, and semaphores in the <code>with</code> statement ==
+
== with 语句中使用锁、条件和信号量 ==
  
All of the objects provided by this module that have <code>acquire()</code> and
+
该模块提供的所有具有 <code>acquire()</code> <code>release()</code> 方法的对象都可以用作 [[../../reference/compound_stmts#with|with]] 语句的上下文管理器。 <code>acquire()</code>方法会在进入block时调用,<code>release()</code>方法会在block退出时调用。 因此,以下代码段:
<code>release()</code> methods can be used as context managers for a [[../../reference/compound_stmts#with|<code>with</code>]]
 
statement. The <code>acquire()</code> method will be called when the block is
 
entered, and <code>release()</code> will be called when the block is exited. Hence,
 
the following snippet:
 
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第1,091行: 第735行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>with some_lock:
+
<syntaxhighlight lang="python3">with some_lock:
     # do something...</pre>
+
     # do something...</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
is equivalent to:
+
相当于:
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第1,103行: 第747行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>some_lock.acquire()
+
<syntaxhighlight lang="python3">some_lock.acquire()
 
try:
 
try:
 
     # do something...
 
     # do something...
 
finally:
 
finally:
     some_lock.release()</pre>
+
     some_lock.release()</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Currently, [[#threading.Lock|<code>Lock</code>]], [[#threading.RLock|<code>RLock</code>]], [[#threading.Condition|<code>Condition</code>]],
+
目前,[[#threading.Lock|Lock]][[#threading.RLock|RLock]][[#threading.Condition|Condition]][[#threading.Semaphore|Semaphore]][[#threading.BoundedSemaphore|BoundedSemaphore]]对象可以用作 [[../../reference/compound_stmts#with|with]] 语句上下文管理器。
[[#threading.Semaphore|<code>Semaphore</code>]], and [[#threading.BoundedSemaphore|<code>BoundedSemaphore</code>]] objects may be used as
 
[[../../reference/compound_stmts#with|<code>with</code>]] statement context managers.
 
  
  
 
</div>
 
</div>
 +
 +
</div>
 +
<div class="clearer">
 +
 +
  
 
</div>
 
</div>
  
[[Category:Python 3.9 中文文档]]
+
[[Category:Python 3.9 文档]]

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

threading — 基于线程的并行性

源代码: :source:`Lib/threading.py`



该模块在较低级别的 _thread 模块的顶部构造更高级别的线程接口。 另请参阅 queue 模块。

3.7 版本变更: 该模块以前是可选的,现在一直可用。


笔记

虽然下面没有列出它们,但该模块仍然支持 Python 2.x 系列中该模块中某些方法和函数使用的 camelCase 名称。


该模块定义了以下功能:

threading.active_count()
返回当前活动的 Thread 对象的数量。 返回的计数等于 enumerate() 返回的列表的长度。
threading.current_thread()
返回当前的 Thread 对象,对应于调用者的控制线程。 如果调用者的控制线程不是通过 threading 模块创建的,则返回一个功能有限的虚拟线程对象。
threading.excepthook(args, /)

处理由 Thread.run() 引发的未捕获异常。

args 参数具有以下属性:

  • exc_type:异常类型。

  • exc_value:异常值,可以是None

  • exc_traceback:异常回溯,可以是None

  • thread:引发异常的线程,可以是None

如果 exc_typeSystemExit,异常会被静默忽略。 否则,异常会打印在 sys.stderr 上。

如果此函数引发异常,则会调用 sys.excepthook() 来处理它。

threading.excepthook() 可以被覆盖以控制如何处理 Thread.run() 引发的未捕获异常。

使用自定义钩子存储 exc_value 可以创建引用循环。 当不再需要异常时,应该明确清除它以中断引用循环。

如果将 thread 设置为正在完成的对象,则使用自定义钩子存储 thread 可以使其复活。 避免在自定义钩子完成后存储 thread 以避免复活对象。

也可以看看

sys.excepthook() 处理未捕获的异常。

3.8 版中的新功能。

threading.get_ident()

返回当前线程的“线程标识符”。 这是一个非零整数。 它的价值没有直接的意义; 它旨在用作魔术饼干,例如 索引线程特定数据的字典。 当一个线程退出并创建另一个线程时,线程标识符可能会被回收。

3.3 版中的新功能。

threading.get_native_id()

返回内核分配的当前线程的本机整数线程 ID。 这是一个非负整数。 它的值可用于在系统范围内唯一标识此特定线程(直到线程终止,之后该值可由操作系统回收)。

3.8 版中的新功能。

threading.enumerate()
返回当前活动的所有 Thread 对象的列表。 该列表包括由 current_thread() 创建的守护线程和虚拟线程对象。 它不包括终止的线程和尚未启动的线程。 但是,主线程始终是结果的一部分,即使在终止时也是如此。
threading.main_thread()

返回主要的 Thread 对象。 在正常情况下,主线程是启动 Python 解释器的线程。

3.4 版中的新功能。

threading.settrace(func)
为从 threading 模块启动的所有线程设置跟踪函数。 func 将在每个线程的 run() 方法被调用之前传递给 sys.settrace()
threading.setprofile(func)
为从 threading 模块启动的所有线程设置配置文件函数。 func 将在每个线程的 run() 方法被调用之前传递给 sys.setprofile()
threading.stack_size([size])
返回创建新线程时使用的线程堆栈大小。 可选的 size 参数指定用于后续创建的线程的堆栈大小,并且必须为 0(使用平台或配置的默认值)或至少为 32,768 (32 KiB) 的正整数值。 如果未指定 size,则使用 0。 如果不支持更改线程堆栈大小,则会引发 RuntimeError。 如果指定的堆栈大小无效,则会引发 ValueError 并且堆栈大小未修改。 32 KiB 目前是支持的最小堆栈大小值,以保证解释器本身有足够的堆栈空间。 请注意,某些平台可能对堆栈大小的值有特定限制,例如要求最小堆栈大小 > 32 KiB 或要求以系统内存页面大小的倍数进行分配 - 应参考平台文档以获取更多信息(4 KiB 页很常见;如果没有更具体的信息,建议使用 4096 的倍数作为堆栈大小)。

该模块还定义了以下常量:

threading.TIMEOUT_MAX

阻塞函数的 timeout 参数允许的最大值 (Lock.acquire(), RLock.acquire(), Condition.wait() 等)。 指定大于此值的超时将引发 OverflowError

3.2 版中的新功能。

该模块定义了许多类,在下面的部分中进行了详细说明。

该模块的设计松散地基于 Java 的线程模型。 然而,Java 使锁和条件变量成为每个对象的基本行为,它们在 Python 中是独立的对象。 Python 的 Thread 类支持 Java 的 Thread 类的行为子集; 目前,没有优先级,没有线程组,线程不能被销毁、停止、暂停、恢复或中断。 Java Thread 类的静态方法在实现时被映射到模块级函数。

下面描述的所有方法都是以原子方式执行的。

线程本地数据

线程本地数据是其值是线程特定的数据。 要管理线程本地数据,只需创建 local(或子类)的实例并在其上存储属性:

mydata = threading.local()
mydata.x = 1

对于不同的线程,实例的值会有所不同。

class threading.local

表示线程本地数据的类。

有关更多详细信息和大量示例,请参阅 _threading_local 模块的文档字符串。


线程对象

Thread 类表示在单独的控制线程中运行的活动。 有两种方法可以指定活动:通过将可调用对象传递给构造函数,或通过覆盖子类中的 run() 方法。 不应在子类中覆盖其他方法(构造函数除外)。 换句话说,only 覆盖了这个类的 __init__()run() 方法。

创建线程对象后,必须通过调用线程的 start() 方法启动其活动。 这会在单独的控制线程中调用 run() 方法。

一旦线程的活动开始,线程就被认为是“活动的”。 当它的 run() 方法终止时,它停止活动——正常情况下,或者通过引发未处理的异常。 is_alive() 方法测试线程是否处于活动状态。

其他线程可以调用线程的 join() 方法。 这会阻塞调用线程,直到调用其 join() 方法的线程终止。

一个线程有一个名字。 名称可以传递给构造函数,并通过 name 属性读取或更改。

如果 run() 方法引发异常,则会调用 threading.excepthook() 来处理它。 默认情况下,threading.excepthook() 静默忽略 SystemExit

一个线程可以被标记为“守护线程”。 这个标志的意义在于,当只剩下守护线程时,整个 Python 程序就会退出。 初始值是从创建线程继承的。 该标志可以通过 daemon 属性或 daemon 构造函数参数设置。

笔记

守护线程在关机时突然停止。 他们的资源(如打开的文件、数据库事务等)可能无法正常释放。 如果您希望您的线程正常停止,请将它们设为非守护进程并使用合适的信号机制,例如 Event


有一个“主线程”对象; 这对应于 Python 程序中的初始控制线程。 它不是守护线程。

有可能创建“虚拟线程对象”。 这些是与“外来线程”相对应的线程对象,它们是在线程模块之外启动的控制线程,例如直接从 C 代码启动。 虚拟线程对象的功能有限; 它们总是被认为是活着的和守护进程,并且不能被 join()ed。 它们永远不会被删除,因为不可能检测到外来线程的终止。

class threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)

应始终使用关键字参数调用此构造函数。 参数是:

应为None; 为将来实现 ThreadGroup 类时的扩展保留。

target 是由 run() 方法调用的可调用对象。 默认为 None,意味着什么都不调用。

name 是线程名称。 默认情况下,唯一名称的构造形式为“Thread-N”,其中 N 是一个小十进制数。

args 是目标调用的参数元组。 默认为 ()

kwargs 是目标调用的关键字参数字典。 默认为 {}

如果不是 None,则 daemon 明确设置线程是否是守护进程。 如果是 None(默认值),守护进程属性是从当前线程继承的。

如果子类覆盖了构造函数,它必须确保在对线程执行任何其他操作之前调用基类构造函数 (Thread.__init__())。

在 3.3 版更改: 添加了 守护进程 参数。

start()

启动线程的活动。

每个线程对象最多必须调用一次。 它安排在单独的控制线程中调用对象的 run() 方法。

如果在同一个线程对象上多次调用此方法,则会引发 RuntimeError

run()

表示线程活动的方法。

您可以在子类中覆盖此方法。 标准的 run() 方法调用传递给对象构造函数的可调用对象作为 target 参数,如果有的话,位置和关键字参数取自 argskwargs 参数,分别。

join(timeout=None)

等待线程终止。 这会阻塞调用线程,直到调用其 join() 方法的线程终止 - 通常或通过未处理的异常 - 或直到发生可选超时。

timeout 参数存在而不是 None 时,它应该是一个浮点数,以秒(或其分数)为单位指定操作超时。 由于 join() 总是返回 None,你必须在 join() 之后调用 is_alive() 来决定是否发生超时 - 如果线程仍然存在,join() 调用超时。

timeout 参数不存在或 None 时,操作将阻塞,直到线程终止。

一个线程可以被 join()ed 多次。

join() 如果尝试加入当前线程,则会引发 RuntimeError,因为这会导致死锁。 在线程启动之前 join() 线程也是一个错误,并且尝试这样做会引发相同的异常。

name

仅用于识别目的的字符串。 它没有语义。 多个线程可能会被赋予相同的名称。 初始名称由构造函数设置。

getName()
setName()

name 的旧 getter/setter API; 直接将其用作属性。

ident

此线程的“线程标识符”或 None(如果该线程尚未启动)。 这是一个非零整数。 请参阅 get_ident() 函数。 当一个线程退出并创建另一个线程时,线程标识符可能会被回收。 即使在线程退出后,标识符仍然可用。

native_id

此线程的本机完整线程 ID。 这是一个非负整数,如果线程尚未启动,则为 None。 请参阅 get_native_id() 函数。 这表示由操作系统(内核)分配给线程的线程 ID (TID)。 它的值可用于在系统范围内唯一标识此特定线程(直到线程终止,之后该值可由操作系统回收)。

笔记

与进程 ID 类似,线程 ID 仅从创建线程到线程终止期间有效(保证在系统范围内唯一)。

3.8 版中的新功能。

is_alive()

返回线程是否存活。

该方法在 run() 方法开始之前返回 True,直到 run() 方法终止之后。 模块函数 enumerate() 返回所有活动线程的列表。

daemon

一个布尔值,指示此线程是否为守护线程 (True) 或不是 (False)。 这必须在调用 start() 之前设置,否则会引发 RuntimeError。 它的初始值是从创建线程继承的; 主线程不是守护线程,因此在主线程中创建的所有线程默认为 daemon = False

当没有存活的非守护线程时,整个 Python 程序就会退出。

isDaemon()
setDaemon()

daemon 的旧 getter/setter API; 直接将其用作属性。


锁定对象

原语锁是一种同步原语,锁定时不属于特定线程。 在 Python 中,它是目前可用的最低级同步原语,由 _thread 扩展模块直接实现。

原始锁处于“锁定”或“解锁”两种状态之一。 它是在解锁状态下创建的。 它有两个基本方法,acquire()release()。 当状态解锁时, acquire() 将状态更改为锁定并立即返回。 当状态被锁定时,acquire() 阻塞,直到另一个线程中对 release() 的调用将其更改为解锁,然后 acquire() 调用重置它锁定并返回。 release() 方法只能在锁定状态下调用; 它将状态更改为解锁并立即返回。 如果尝试释放未锁定的锁,则会引发 RuntimeError

锁还支持 上下文管理协议

acquire()中多个线程被阻塞等待状态变为unlocked时,当release()调用将状态重置为unlocked时,只有一个线程继续执行; 未定义等待线程中的哪一个进行,并且可能因实现而异。

所有方法都是原子执行的。

class threading.Lock

实现原始锁对象的类。 一旦一个线程获得了一个锁,后续的获得它的尝试就会阻塞,直到它被释放; 任何线程都可以释放它。

请注意, Lock 实际上是一个工厂函数,它返回平台支持的具体 Lock 类的最有效版本的实例。

acquire(blocking=True, timeout=- 1)

获取锁,阻塞或非阻塞。

当调用 blocking 参数设置为 True(默认值)时,阻塞直到锁被解锁,然后将其设置为锁定并返回 True

当调用 blocking 参数设置为 False 时,不要阻塞。 如果 blocking 设置为 True 的调用会阻塞,则立即返回 False; 否则,设置锁为locked并返回True

在将浮点 timeout 参数设置为正值的情况下调用时,最多阻塞 timeout 指定的秒数,并且只要无法获取锁。 -1timeout 参数指定无限等待。 当 blocking 为 false 时,禁止指定 timeout

如果成功获取锁,则返回值为 True,否则返回值为 False(例如,如果 timeout 已过期)。

3.2 版更改: timeout 参数是新的。

3.2 版更改: 如果底层线程实现支持,现在可以被 POSIX 上的信号中断获取锁。

release()

释放锁。 这可以从任何线程调用,而不仅仅是获取锁的线程。

当锁被锁定时,将其重置为解锁,然后返回。 如果任何其他线程在等待锁定解锁时被阻塞,则只允许其中一个线程继续执行。

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

没有返回值。

locked()

如果获得了锁,则返回 true。


RLock 对象

重入锁是一个同步原语,可以被同一个线程多次获取。 在内部,除了原始锁使用的锁定/解锁状态之外,它还使用“拥有线程”和“递归级别”的概念。 在锁定状态下,某个线程拥有锁; 在解锁状态下,没有线程拥有它。

为了锁定锁,线程调用其 acquire() 方法; 一旦线程拥有锁,它就会返回。 要解锁锁,线程调用其 release() 方法。 acquire()/release() 调用对可以嵌套; 只有最后的 release()(最外面对的 release())将锁重置为解锁状态,并允许在 acquire() 中阻塞的另一个线程继续进行.

可重入锁还支持 [X33X] 上下文管理协议 。

class threading.RLock

此类实现可重入锁对象。 重入锁必须由获取它的线程释放。 一旦一个线程获得了可重入锁,同一个线程就可以再次获得它而不会阻塞; 线程每次获得它时都必须释放一次。

请注意,RLock 实际上是一个工厂函数,它返回平台支持的具体 RLock 类的最有效版本的实例。

acquire(blocking=True, timeout=- 1)

获取锁,阻塞或非阻塞。

不带参数调用时:如果此线程已拥有锁,则将递归级别增加 1,并立即返回。 否则,如果另一个线程拥有锁,则阻塞直到锁被解锁。 一旦锁被解锁(不属于任何线程),然后获取所有权,将递归级别设置为 1,然后返回。 如果有多个线程在等待锁被解锁之前被阻塞,则一次只有一个线程能够获取锁的所有权。 在这种情况下没有返回值。

blocking 参数设置为 true 的情况下调用时,执行与不带参数调用时相同的操作,并返回 True

当在 blocking 参数设置为 false 的情况下调用时,不要阻塞。 如果没有参数的调用会阻塞,立即返回 False; 否则,执行与不带参数调用时相同的操作,并返回 True

在将浮点 timeout 参数设置为正值的情况下调用时,最多阻塞 timeout 指定的秒数,并且只要无法获取锁。 如果已获取锁,则返回 True,如果超时已过,则返回 false。

3.2 版更改: timeout 参数是新的。

release()

释放锁,递减递归级别。 如果递减后它为零,则将锁重置为解锁(不属于任何线程),并且如果任何其他线程被阻塞等待锁解锁,则只允许其中一个线程继续进行。 如果递减后递归级别仍然不为零,则锁保持锁定并由调用线程拥有。

仅当调用线程拥有锁时才调用此方法。 如果在解锁时调用此方法,则会引发 RuntimeError

没有返回值。


条件对象

条件变量总是与某种锁相关联; 这可以传入或默认创建一个。 当多个条件变量必须共享同一个锁时,传入一个很有用。 锁是条件对象的一部分:您不必单独跟踪它。

条件变量遵循 上下文管理协议 :使用 with 语句在封闭块的持续时间内获取关联的锁。 acquire()release() 方法也调用了关联锁的对应方法。

必须在持有相关锁的情况下调用其他方法。 wait() 方法释放锁,然后阻塞,直到另一个线程通过调用 notify()notify_all() 唤醒它。 一旦被唤醒,wait() 重新获取锁并返回。 也可以指定超时。

notify() 方法唤醒等待条件变量的线程之一(如果有任何等待)。 notify_all() 方法唤醒所有等待条件变量的线程。

注意:notify()notify_all() 方法不会释放锁; 这意味着被唤醒的线程不会立即从它们的 wait() 调用中返回,而是只有在调用 notify()notify_all() 的线程时才返回] 最后放弃锁的所有权。

使用条件变量的典型编程风格使用锁来同步对某些共享状态的访问; 对特定状态更改感兴趣的线程重复调用 wait() 直到他们看到所需的状态,而修改状态的线程调用 notify()notify_all( ) 当他们以这样一种方式改变状态时,它可能是其中一个服务员想要的状态。 例如,以下代码是具有无限缓冲区容量的通用生产者-消费者情况:

# Consume one item
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# Produce one item
with cv:
    make_an_item_available()
    cv.notify()

while 循环检查应用程序的条件是必要的,因为 wait() 可以在任意长时间后返回,并且提示 notify() 调用的条件可能不再成立。 这是多线程编程所固有的。 wait_for() 方法可用于自动进行条件检查,并简化超时计算:

# Consume an item
with cv:
    cv.wait_for(an_item_is_available)
    get_an_available_item()

要在 notify()notify_all() 之间进行选择,请考虑一种状态更改是否只对一个或多个等待线程感兴趣。 例如 在典型的生产者-消费者情况下,将一项添加到缓冲区只需要唤醒一个消费者线程。

class threading.Condition(lock=None)

此类实现条件变量对象。 条件变量允许一个或多个线程等待,直到它们被另一个线程通知。

如果给出了 lock 参数而不是 None,则它必须是 LockRLock 对象,并用作底层锁. 否则,将创建一个新的 RLock 对象并将其用作底层锁。

3.3 版更改: 从工厂函数更改为类。

acquire(*args)

获取底层锁。 该方法调用底层锁上的相应方法; 返回值是该方法返回的任何值。

release()

释放底层锁。 该方法调用底层锁上的相应方法; 没有返回值。

wait(timeout=None)

等到通知或直到发生超时。 如果调用此方法时调用线程尚未获取锁,则会引发 RuntimeError

此方法释放底层锁,然后阻塞直到它被另一个线程中的相同条件变量的 notify()notify_all() 调用唤醒,或者直到可选超时发生。 一旦被唤醒或超时,它会重新获取锁并返回。

timeout 参数存在而不是 None 时,它应该是一个浮点数,以秒(或其分数)为单位指定操作超时。

当底层锁是 RLock 时,它不会使用其 release() 方法释放,因为当它被多次递归获取时,这可能实际上不会解锁锁。 取而代之的是,使用了 RLock 类的内部接口,即使在多次递归获取时,它也能真正解锁它。 然后使用另一个内部接口在重新获取锁时恢复递归级别。

返回值是 True,除非给定的 timeout 过期,在这种情况下它是 False

3.2 版本更改: 以前,该方法总是返回 None

wait_for(predicate, timeout=None)

等到条件评估为真。 predicate 应该是一个可调用的结果将被解释为一个布尔值。 可以提供一个 timeout,给出最长的等待时间。

这个实用方法可能会重复调用 wait() 直到满足谓词,或者直到发生超时。 返回值是谓词的最后一个返回值,如果方法超时,它将评估为 False

忽略超时特性,调用这个方法大致相当于写:

while not predicate():
    cv.wait()

因此,应用与 wait() 相同的规则:调用时必须持有锁,并在返回时重新获取。 谓词在持有锁的情况下进行评估。

3.2 版中的新功能。

notify(n=1)

默认情况下,唤醒一个等待此条件的线程(如果有)。 如果调用此方法时调用线程尚未获取锁,则会引发 RuntimeError

该方法最多唤醒n个等待条件变量的线程; 如果没有线程在等待,则为空操作。

如果至少有 n 个线程在等待,当前实现会准确唤醒 n 个线程。 但是,依赖这种行为是不安全的。 未来的优化实现可能偶尔会唤醒超过 n 个线程。

注意:被唤醒的线程实际上不会从它的 wait() 调用中返回,直到它可以重新获取锁。 由于 notify() 不释放锁,它的调用者应该。

notify_all()

唤醒所有在此条件下等待的线程。 此方法的作用类似于 notify(),但唤醒所有等待线程而不是一个。 如果调用此方法时调用线程尚未获取锁,则会引发 RuntimeError


信号量对象

这是计算机科学史上最古老的同步原语之一,由早期的荷兰计算机科学家 Edsger W. Dijkstra(他使用名称 P()V() 而不是 acquire()release())。

信号量管理一个内部计数器,该计数器由每个 acquire() 调用递减,并由每个 release() 调用递增。 计数器永远不会低于零; 当 acquire() 发现它为零时,它会阻塞,等待其他线程调用 release()

信号量还支持 上下文管理协议

class threading.Semaphore(value=1)

这个类实现了信号量对象。 信号量管理一个原子计数器,表示 release() 调用的数量减去 acquire() 调用的数量,再加上一个初始值。 acquire() 方法在必要时阻塞,直到它可以在不使计数器为负的情况下返回。 如果没有给出,value 默认为 1。

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

3.3 版更改: 从工厂函数更改为类。

acquire(blocking=True, timeout=None)

获取信号量。

不带参数调用时:

  • 如果内部计数器在进入时大于零,则将其减一并立即返回 True

  • 如果内部计数器在进入时为零,则阻塞直到被调用 release() 唤醒。 一旦唤醒(并且计数器大于 0),将计数器减 1 并返回 True。 每次调用 release() 都会唤醒一个线程。 不应依赖线程被唤醒的顺序。

当在 blocking 设置为 false 的情况下调用时,不要阻止。 如果没有参数的调用会阻塞,立即返回 False; 否则,执行与不带参数调用时相同的操作,并返回 True

当使用 None 以外的 timeout 调用时,它最多会阻塞 timeout 秒。 如果在该时间间隔内未成功完成获取,则返回 False。 否则返回 True

3.2 版更改: timeout 参数是新的。

release(n=1)

释放信号量,将内部计数器增加 n。 当它在进入时为零并且其他线程正在等待它再次变得大于零时,唤醒这些线程的 n

3.9 版更改: 增加了 n 参数,可以一次性释放多个等待线程。

class threading.BoundedSemaphore(value=1)

实现有界信号量对象的类。 有界信号量检查以确保其当前值不超过其初始值。 如果是,则引发 ValueError。 在大多数情况下,信号量用于保护容量有限的资源。 如果信号量被释放太多次,则表明存在错误。 如果没有给出,value 默认为 1。

3.3 版更改: 从工厂函数更改为类。

信号量示例

信号量通常用于保护容量有限的资源,例如数据库服务器。 在资源大小固定的任何情况下,您都应该使用有界信号量。 在产生任何工作线程之前,您的主线程将初始化信号量:

maxconnections = 5
# ...
pool_sema = BoundedSemaphore(value=maxconnections)

一旦产生,工作线程在需要连接到服务器时调用信号量的获取和释放方法:

with pool_sema:
    conn = connectdb()
    try:
        # ... use connection ...
    finally:
        conn.close()

有界信号量的使用降低了导致信号量释放多于获取量的编程错误未被检测到的可能性。


事件对象

这是线程之间最简单的通信机制之一:一个线程发出事件信号,其他线程等待它。

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

class threading.Event

实现事件对象的类。 事件管理一个标志,该标志可以使用 set() 方法设置为 true,并使用 clear() 方法重置为 false。 wait() 方法阻塞,直到标志为真。 该标志最初为假。

3.3 版更改: 从工厂函数更改为类。

is_set()

当且仅当内部标志为真时返回 True

set()

将内部标志设置为 true。 所有等待它变为真的线程都被唤醒。 一旦标志为真,调用 wait() 的线程根本不会阻塞。

clear()

将内部标志重置为 false。 随后,调用 wait() 的线程将阻塞,直到调用 set() 再次将内部标志设置为 true。

wait(timeout=None)

阻塞直到内部标志为真。 如果内部标志在进入时为真,则立即返回。 否则,阻塞直到另一个线程调用 set() 将标志设置为 true,或者直到发生可选超时。

当 timeout 参数存在而不是 None 时,它应该是一个浮点数,以秒(或其分数)为单位指定操作超时。

此方法返回 True 当且仅当内部标志已设置为 true 时,无论是在等待调用之前还是等待开始之后,因此它将始终返回 True 除非给出超时并且操作超时。

3.1 更改: 以前,该方法总是返回 None


定时器对象

这个类代表一个只有在经过一定时间后才应该运行的动作——一个计时器。 TimerThread 的子类,因此也可以作为创建自定义线程的示例。

定时器与线程一样,通过调用它们的 start() 方法启动。 可以通过调用 cancel() 方法来停止计时器(在其动作开始之前)。 计时器在执行其操作之前将等待的时间间隔可能与用户指定的时间间隔不完全相同。

例如:

def hello():
    print("hello, world")

t = Timer(30.0, hello)
t.start()  # after 30 seconds, "hello, world" will be printed
class threading.Timer(interval, function, args=None, kwargs=None)

创建一个计时器,在 interval 秒过去后,使用参数 args 和关键字参数 kwargs 运行 function。 如果 argsNone(默认值),则将使用空列表。 如果 kwargsNone(默认值),则将使用空字典。

3.3 版更改: 从工厂函数更改为类。

cancel()

停止定时器,并取消定时器动作的执行。 这仅在计时器仍处于等待阶段时才有效。


障碍物

3.2 版中的新功能。


此类提供了一个简单的同步原语,供需要相互等待的固定数量的线程使用。 每个线程都试图通过调用 wait() 方法来通过屏障,并且会一直阻塞,直到所有线程都进行了 wait() 调用。 此时,线程同时释放。

对于相同数量的线程,屏障可以重复使用任意次数。

例如,这里有一个简单的方法来同步客户端和服务器线程:

b = Barrier(2, timeout=5)

def server():
    start_server()
    b.wait()
    while True:
        connection = accept_connection()
        process_server_connection(connection)

def client():
    b.wait()
    while True:
        connection = make_connection()
        process_client_connection(connection)
class threading.Barrier(parties, action=None, timeout=None)

个线程创建屏障对象。 action,当提供时,是一个可调用的,当它们被释放时由其中一个线程调用。 timeout 是默认超时值,如果没有为 wait() 方法指定。

wait(timeout=None)

通过障碍。 当屏障的所有线程都调用了这个函数时,它们都被同时释放。 如果提供了 timeout,则它优先于提供给类构造函数的任何内容使用。

返回值是 0 到 party – 1 范围内的整数,每个线程都不同。 这可以用来选择一个线程来做一些特殊的内务处理,例如:

i = barrier.wait()
if i == 0:
    # Only one thread needs to print this
    print("passed the barrier")

如果向构造函数提供了 action,其中一个线程将在释放之前调用它。 如果此调用引发错误,则屏障将进入损坏状态。

如果调用超时,屏障将进入破坏状态。

如果在线程等待时屏障被破坏或重置,此方法可能会引发 BrokenBarrierError 异常。

reset()

将障碍返回到默认的空状态。 任何等待它的线程都会收到 BrokenBarrierError 异常。

请注意,如果存在状态未知的其他线程,则使用此函数可能需要一些外部同步。 如果障碍被打破,最好离开它并创建一个新的障碍。

abort()

将屏障置于破碎状态。 这会导致对 wait() 的任何活动或未来调用失败,并显示 BrokenBarrierError。 例如,如果其中一个线程需要中止,请使用此选项,以避免死锁应用程序。

最好使用合理的 timeout 值简单地创建屏障,以自动防止其中一个线程出错。

parties

通过屏障所需的线程数。

n_waiting

当前在屏障中等待的线程数。

broken

如果障碍处于损坏状态,则为 True 的布尔值。

exception threading.BrokenBarrierError
这个异常是 RuntimeError 的子类,当 Barrier 对象被重置或损坏时会引发。


在 with 语句中使用锁、条件和信号量

该模块提供的所有具有 acquire()release() 方法的对象都可以用作 with 语句的上下文管理器。 acquire()方法会在进入block时调用,release()方法会在block退出时调用。 因此,以下代码段:

with some_lock:
    # do something...

相当于:

some_lock.acquire()
try:
    # do something...
finally:
    some_lock.release()

目前,LockRLockConditionSemaphoreBoundedSemaphore对象可以用作 with 语句上下文管理器。