“Python/docs/3.9/library/ thread”的版本间差异
(autoload) |
小 (Page commit) |
||
第1行: | 第1行: | ||
+ | {{DISPLAYTITLE:_thread — 低级线程 API — Python 文档}} | ||
<div id="module-_thread" class="section"> | <div id="module-_thread" class="section"> | ||
<span id="thread-low-level-threading-api"></span> | <span id="thread-low-level-threading-api"></span> | ||
− | = | + | = _thread — 低级线程 API = |
− | + | ||
− | + | ----- | |
− | + | ||
− | + | 该模块提供用于处理多线程(也称为 ''轻量级进程'' 或 ''任务'' )的低级原语——多个控制线程共享其全局数据空间。 对于同步,提供了简单的锁(也称为 ''互斥锁'' 或 ''二进制信号量'' )。 [[../threading#module-threading|threading]] 模块提供了一个更易于使用的高级线程 API,该 API 构建在该模块之上。 | |
− | |||
− | |||
<div id="index-1" class="versionchanged"> | <div id="index-1" class="versionchanged"> | ||
− | <span class="versionmodified changed"> | + | <span class="versionmodified changed"> 3.7 版本变更: </span> 该模块以前是可选的,现在一直可用。 |
</div> | </div> | ||
− | + | 该模块定义了以下常量和函数: | |
<dl> | <dl> | ||
− | <dt><span id="_thread.error"></span>''exception'' < | + | <dt><span id="_thread.error"></span>''<span class="pre">exception</span>'' <span class="sig-prename descclassname"><span class="pre">_thread.</span></span><span class="sig-name descname"><span class="pre">error</span></span></dt> |
− | <dd><p> | + | <dd><p>引发线程特定的错误。</p> |
<div class="versionchanged"> | <div class="versionchanged"> | ||
− | <p><span class="versionmodified changed"> | + | <p><span class="versionmodified changed"> 3.3 版更改: </span> 现在是内置 [[../exceptions#RuntimeError|RuntimeError]] 的同义词。</p> |
</div></dd></dl> | </div></dd></dl> | ||
− | ; <span id="_thread.LockType"></span>< | + | ; <span id="_thread.LockType"></span><span class="sig-prename descclassname"><span class="pre">_thread.</span></span><span class="sig-name descname"><span class="pre">LockType</span></span> |
− | : | + | : 这是锁对象的类型。 |
<dl> | <dl> | ||
− | <dt><span id="_thread.start_new_thread"></span>< | + | <dt><span id="_thread.start_new_thread"></span><span class="sig-prename descclassname"><span class="pre">_thread.</span></span><span class="sig-name descname"><span class="pre">start_new_thread</span></span><span class="sig-paren">(</span>''<span class="pre">function</span>'', ''<span class="pre">args</span>''<span class="optional">[</span>, ''<span class="pre">kwargs</span>''<span class="optional">]</span><span class="sig-paren">)</span></dt> |
− | <dd><p> | + | <dd><p>启动一个新线程并返回其标识符。 线程使用参数列表 ''args''(必须是元组)执行函数 ''function''。 可选的 ''kwargs'' 参数指定关键字参数的字典。</p> |
− | + | <p>当函数返回时,线程默默地退出。</p> | |
− | + | <p>当函数因未处理的异常而终止时,会调用 [[../sys#sys|sys.unraisablehook()]] 来处理异常。 钩子参数的 ''object'' 属性是 ''function''。 默认情况下,打印堆栈跟踪,然后线程退出(但其他线程继续运行)。</p> | |
− | <p> | + | <p>当函数引发 [[../exceptions#SystemExit|SystemExit]] 异常时,它会被静默忽略。</p> |
− | <p> | ||
− | [[../sys#sys| | ||
− | |||
− | |||
− | <p> | ||
− | |||
<div class="versionchanged"> | <div class="versionchanged"> | ||
− | <p><span class="versionmodified changed"> | + | <p><span class="versionmodified changed"> 3.8 版更改: </span>[[../sys#sys|sys.unraisablehook()]] 现在用于处理未处理的异常。</p> |
</div></dd></dl> | </div></dd></dl> | ||
<dl> | <dl> | ||
− | <dt><span id="_thread.interrupt_main"></span>< | + | <dt><span id="_thread.interrupt_main"></span><span class="sig-prename descclassname"><span class="pre">_thread.</span></span><span class="sig-name descname"><span class="pre">interrupt_main</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt> |
− | <dd><p> | + | <dd><p>模拟一个 [[../signal#signal|signal.SIGINT]] 信号到达主线程的效果。 一个线程可以使用这个函数来中断主线程。</p> |
− | + | <p>如果 [[../signal#signal|signal.SIGINT]] 没有被 Python 处理(它被设置为 [[../signal#signal|signal.SIG_DFL]] 或 [[../signal#signal|signal.SIG_IGN]]),这个函数什么都不做。</p></dd></dl> | |
− | <p> | ||
− | [[../signal#signal| | ||
− | |||
− | ; <span id="_thread.exit"></span>< | + | ; <span id="_thread.exit"></span><span class="sig-prename descclassname"><span class="pre">_thread.</span></span><span class="sig-name descname"><span class="pre">exit</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> |
− | : | + | : 引发 [[../exceptions#SystemExit|SystemExit]] 异常。 如果没有被捕获,这将导致线程静默退出。 |
− | ; <span id="_thread.allocate_lock"></span>< | + | ; <span id="_thread.allocate_lock"></span><span class="sig-prename descclassname"><span class="pre">_thread.</span></span><span class="sig-name descname"><span class="pre">allocate_lock</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> |
− | : | + | : 返回一个新的锁对象。 下面描述了锁的方法。 锁最初是解锁的。 |
− | ; <span id="_thread.get_ident"></span>< | + | ; <span id="_thread.get_ident"></span><span class="sig-prename descclassname"><span class="pre">_thread.</span></span><span class="sig-name descname"><span class="pre">get_ident</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> |
− | : | + | : 返回当前线程的“线程标识符”。 这是一个非零整数。 它的价值没有直接的意义; 它旨在用作魔术饼干,例如 索引线程特定数据的字典。 当一个线程退出并创建另一个线程时,线程标识符可能会被回收。 |
<dl> | <dl> | ||
− | <dt><span id="_thread.get_native_id"></span>< | + | <dt><span id="_thread.get_native_id"></span><span class="sig-prename descclassname"><span class="pre">_thread.</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> | + | <dd><p>返回内核分配的当前线程的本机整数线程 ID。 这是一个非负整数。 它的值可用于在系统范围内唯一标识此特定线程(直到线程终止,之后该值可由操作系统回收)。</p> |
− | |||
− | |||
− | |||
− | |||
<div class="versionadded"> | <div class="versionadded"> | ||
− | <p><span class="versionmodified added">3.8 | + | <p><span class="versionmodified added">3.8 版中的新功能。</span></p> |
</div></dd></dl> | </div></dd></dl> | ||
− | + | ; <span id="_thread.stack_size"></span><span class="sig-prename descclassname"><span class="pre">_thread.</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> | |
− | + | : 返回创建新线程时使用的线程堆栈大小。 可选的 ''size'' 参数指定用于后续创建的线程的堆栈大小,并且必须为 0(使用平台或配置的默认值)或至少为 32,768 (32 KiB) 的正整数值。 如果未指定 ''size'',则使用 0。 如果不支持更改线程堆栈大小,则会引发 [[../exceptions#RuntimeError|RuntimeError]]。 如果指定的堆栈大小无效,则会引发 [[../exceptions#ValueError|ValueError]] 并且堆栈大小未修改。 32 KiB 目前是支持的最小堆栈大小值,以保证解释器本身有足够的堆栈空间。 请注意,某些平台可能对堆栈大小的值有特定限制,例如要求最小堆栈大小 > 32 KiB 或要求以系统内存页面大小的倍数进行分配 - 应参考平台文档以获取更多信息(4 KiB 页很常见;如果没有更具体的信息,建议使用 4096 的倍数作为堆栈大小)。 | |
− | |||
− | ''size'' | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
<dl> | <dl> | ||
− | <dt><span id="_thread.TIMEOUT_MAX"></span>< | + | <dt><span id="_thread.TIMEOUT_MAX"></span><span class="sig-prename descclassname"><span class="pre">_thread.</span></span><span class="sig-name descname"><span class="pre">TIMEOUT_MAX</span></span></dt> |
− | <dd><p> | + | <dd><p><code>Lock.acquire()</code> 的 ''timeout'' 参数允许的最大值。 指定大于此值的超时将引发 [[../exceptions#OverflowError|OverflowError]]。</p> |
− | <code>Lock.acquire()</code> | ||
− | |||
<div class="versionadded"> | <div class="versionadded"> | ||
− | <p><span class="versionmodified added">3.2 | + | <p><span class="versionmodified added">3.2 版中的新功能。</span></p> |
</div></dd></dl> | </div></dd></dl> | ||
− | + | 锁对象有以下方法: | |
<dl> | <dl> | ||
− | <dt><span id="_thread.lock.acquire"></span>< | + | <dt><span id="_thread.lock.acquire"></span><span class="sig-prename descclassname"><span class="pre">lock.</span></span><span class="sig-name descname"><span class="pre">acquire</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">waitflag</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">1</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> | + | <dd><p>在没有任何可选参数的情况下,此方法无条件地获取锁,如有必要,等待它被另一个线程释放(一次只有一个线程可以获取锁——这就是它们存在的原因)。</p> |
− | + | <p>如果存在整数 ''waitflag'' 参数,则操作取决于其值:如果为零,则仅在无需等待即可立即获取时才获取锁,如果不为零,则获取锁无条件如上。</p> | |
− | + | <p>如果浮点 ''timeout'' 参数存在且为正,则它指定返回前的最大等待时间(以秒为单位)。 负 ''timeout'' 参数指定无限等待。 如果 ''waitflag'' 为零,则不能指定 ''timeout''。</p> | |
− | <p> | + | <p>获取锁成功返回值为<code>True</code>,否则返回值为<code>False</code>。</p> |
− | |||
− | |||
− | |||
− | <p> | ||
− | |||
− | ''timeout'' | ||
− | |||
− | <p> | ||
− | <code>False</code> | ||
<div class="versionchanged"> | <div class="versionchanged"> | ||
− | <p><span class="versionmodified changed"> | + | <p><span class="versionmodified changed"> 3.2 版更改: </span> ''timeout'' 参数是新的。</p> |
</div> | </div> | ||
<div class="versionchanged"> | <div class="versionchanged"> | ||
− | <p><span class="versionmodified changed"> | + | <p><span class="versionmodified changed"> 3.2 版更改: </span> 锁定获取现在可以被 POSIX 上的信号中断。</p> |
</div></dd></dl> | </div></dd></dl> | ||
− | ; <span id="_thread.lock.release"></span>< | + | ; <span id="_thread.lock.release"></span><span class="sig-prename descclassname"><span class="pre">lock.</span></span><span class="sig-name descname"><span class="pre">release</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> |
− | : | + | : 释放锁。 该锁必须更早获得,但不一定由同一线程获得。 |
− | ; <span id="_thread.lock.locked"></span>< | + | ; <span id="_thread.lock.locked"></span><span class="sig-prename descclassname"><span class="pre">lock.</span></span><span class="sig-name descname"><span class="pre">locked</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> |
− | : | + | : 返回锁的状态:<code>True</code> 如果它已被某个线程获取,则 <code>False</code> 否则。 |
− | + | 除了这些方法之外,还可以通过 [[../../reference/compound_stmts#with|with]] 语句使用锁定对象,例如: | |
− | [[../../reference/compound_stmts#with| | ||
<div class="highlight-python3 notranslate"> | <div class="highlight-python3 notranslate"> | ||
第149行: | 第108行: | ||
<div class="highlight"> | <div class="highlight"> | ||
− | < | + | <syntaxhighlight lang="python3">import _thread |
a_lock = _thread.allocate_lock() | a_lock = _thread.allocate_lock() | ||
with a_lock: | with a_lock: | ||
− | print( | + | print("a_lock is locked while this executes")</syntaxhighlight> |
</div> | </div> | ||
</div> | </div> | ||
− | ''' | + | '''注意事项:''' |
<blockquote><div> | <blockquote><div> | ||
第166行: | 第125行: | ||
</div></blockquote> | </div></blockquote> | ||
− | * | + | * 线程与中断进行了奇怪的交互:[[../exceptions#KeyboardInterrupt|KeyboardInterrupt]] 异常将被任意线程接收。 (当 [[../signal#module-signal|signal]] 模块可用时,中断总是转到主线程。) |
− | * | + | * 调用 [[../sys#sys|sys.exit()]] 或引发 [[../exceptions#SystemExit|SystemExit]] 异常相当于调用 [[#thread.exit|_thread.exit()]]。 |
− | * | + | * 不可能在锁上中断 <code>acquire()</code> 方法——[[../exceptions#KeyboardInterrupt|KeyboardInterrupt]] 异常将在获取锁后发生。 |
− | * | + | * 当主线程退出时,其他线程是否存活由系统定义。 在大多数系统上,它们在不执行 [[../../reference/compound_stmts#try|try]] ... [[../../reference/compound_stmts#finally|finally]] 子句或执行对象析构函数的情况下被杀死。 |
− | * | + | * 当主线程退出时,它不会执行任何通常的清理(除了 [[../../reference/compound_stmts#try|try]] ... [[../../reference/compound_stmts#finally|finally]] 子句被遵守),并且标准 I/O 文件不会被刷新。 |
+ | |||
+ | |||
+ | </div> | ||
+ | <div class="clearer"> | ||
+ | |||
</div> | </div> | ||
− | [[Category:Python 3.9 | + | [[Category:Python 3.9 文档]] |
2021年10月31日 (日) 04:51的最新版本
_thread — 低级线程 API
该模块提供用于处理多线程(也称为 轻量级进程 或 任务 )的低级原语——多个控制线程共享其全局数据空间。 对于同步,提供了简单的锁(也称为 互斥锁 或 二进制信号量 )。 threading 模块提供了一个更易于使用的高级线程 API,该 API 构建在该模块之上。
3.7 版本变更: 该模块以前是可选的,现在一直可用。
该模块定义了以下常量和函数:
- exception _thread.error
引发线程特定的错误。
3.3 版更改: 现在是内置 RuntimeError 的同义词。
- _thread.LockType
- 这是锁对象的类型。
- _thread.start_new_thread(function, args[, kwargs])
启动一个新线程并返回其标识符。 线程使用参数列表 args(必须是元组)执行函数 function。 可选的 kwargs 参数指定关键字参数的字典。
当函数返回时,线程默默地退出。
当函数因未处理的异常而终止时,会调用 sys.unraisablehook() 来处理异常。 钩子参数的 object 属性是 function。 默认情况下,打印堆栈跟踪,然后线程退出(但其他线程继续运行)。
当函数引发 SystemExit 异常时,它会被静默忽略。
3.8 版更改: sys.unraisablehook() 现在用于处理未处理的异常。
- _thread.interrupt_main()
模拟一个 signal.SIGINT 信号到达主线程的效果。 一个线程可以使用这个函数来中断主线程。
如果 signal.SIGINT 没有被 Python 处理(它被设置为 signal.SIG_DFL 或 signal.SIG_IGN),这个函数什么都不做。
- _thread.exit()
- 引发 SystemExit 异常。 如果没有被捕获,这将导致线程静默退出。
- _thread.allocate_lock()
- 返回一个新的锁对象。 下面描述了锁的方法。 锁最初是解锁的。
- _thread.get_ident()
- 返回当前线程的“线程标识符”。 这是一个非零整数。 它的价值没有直接的意义; 它旨在用作魔术饼干,例如 索引线程特定数据的字典。 当一个线程退出并创建另一个线程时,线程标识符可能会被回收。
- _thread.get_native_id()
返回内核分配的当前线程的本机整数线程 ID。 这是一个非负整数。 它的值可用于在系统范围内唯一标识此特定线程(直到线程终止,之后该值可由操作系统回收)。
3.8 版中的新功能。
- _thread.stack_size([size])
- 返回创建新线程时使用的线程堆栈大小。 可选的 size 参数指定用于后续创建的线程的堆栈大小,并且必须为 0(使用平台或配置的默认值)或至少为 32,768 (32 KiB) 的正整数值。 如果未指定 size,则使用 0。 如果不支持更改线程堆栈大小,则会引发 RuntimeError。 如果指定的堆栈大小无效,则会引发 ValueError 并且堆栈大小未修改。 32 KiB 目前是支持的最小堆栈大小值,以保证解释器本身有足够的堆栈空间。 请注意,某些平台可能对堆栈大小的值有特定限制,例如要求最小堆栈大小 > 32 KiB 或要求以系统内存页面大小的倍数进行分配 - 应参考平台文档以获取更多信息(4 KiB 页很常见;如果没有更具体的信息,建议使用 4096 的倍数作为堆栈大小)。
- _thread.TIMEOUT_MAX
Lock.acquire()
的 timeout 参数允许的最大值。 指定大于此值的超时将引发 OverflowError。3.2 版中的新功能。
锁对象有以下方法:
- lock.acquire(waitflag=1, timeout=- 1)
在没有任何可选参数的情况下,此方法无条件地获取锁,如有必要,等待它被另一个线程释放(一次只有一个线程可以获取锁——这就是它们存在的原因)。
如果存在整数 waitflag 参数,则操作取决于其值:如果为零,则仅在无需等待即可立即获取时才获取锁,如果不为零,则获取锁无条件如上。
如果浮点 timeout 参数存在且为正,则它指定返回前的最大等待时间(以秒为单位)。 负 timeout 参数指定无限等待。 如果 waitflag 为零,则不能指定 timeout。
获取锁成功返回值为
True
,否则返回值为False
。3.2 版更改: timeout 参数是新的。
3.2 版更改: 锁定获取现在可以被 POSIX 上的信号中断。
- lock.release()
- 释放锁。 该锁必须更早获得,但不一定由同一线程获得。
- lock.locked()
- 返回锁的状态:
True
如果它已被某个线程获取,则False
否则。
除了这些方法之外,还可以通过 with 语句使用锁定对象,例如:
注意事项:
- 线程与中断进行了奇怪的交互:KeyboardInterrupt 异常将被任意线程接收。 (当 signal 模块可用时,中断总是转到主线程。)
- 调用 sys.exit() 或引发 SystemExit 异常相当于调用 _thread.exit()。
- 不可能在锁上中断
acquire()
方法——KeyboardInterrupt 异常将在获取锁后发生。 - 当主线程退出时,其他线程是否存活由系统定义。 在大多数系统上,它们在不执行 try ... finally 子句或执行对象析构函数的情况下被杀死。
- 当主线程退出时,它不会执行任何通常的清理(除了 try ... finally 子句被遵守),并且标准 I/O 文件不会被刷新。