17.9. _thread
—低级线程API¶
此模块提供用于处理多线程(也称为 light-weight processes 或 tasks)的低级原语—多个控制线程共享其全局数据空间。对于同步,提供简单锁(也称为 mutexes 或 binary semaphores)。 threading
模块提供了一个更易于使用和更高级别的线程API构建在这个模块的顶部。
模块是可选的。它在Windows,Linux,SGI IRIX,Solaris 2.x以及具有POSIX线程(也称为“pthread”)实现的系统上受支持。对于缺少 _thread
模块的系统,_dummy_thread
模块可用。它复制此模块的接口,并可用作插件替换。
它定义了以下常量和函数:
-
exception
_thread.
error
¶ 引发线程特定的错误。
在 3.3 版更改: 这是现在的内置
RuntimeError
的同义词。
-
_thread.
LockType
¶ 这是锁对象的类型。
-
_thread.
start_new_thread
(function, args[, kwargs])¶ 启动一个新线程并返回其标识符。线程使用参数列表 args (必须是元组)执行函数 function。可选的 kwargs 参数指定关键字参数的字典。当函数返回时,线程静默退出。当函数以未处理的异常终止时,将打印堆栈跟踪,然后线程退出(但其他线程继续运行)。
-
_thread.
interrupt_main
()¶ 在主线程中引发
KeyboardInterrupt
异常。一个子线程可以使用这个函数来中断主线程。
-
_thread.
exit
()¶ 升高
SystemExit
异常。当不被捕获时,这将导致线程静默地退出。
-
_thread.
allocate_lock
()¶ 返回一个新的锁对象。锁的方法如下所述。锁首先解锁。
-
_thread.
get_ident
()¶ 返回当前线程的’线程标识符’。这是一个非零整数。它的价值没有直接的意义;它旨在作为要使用的魔术cookie。索引线程特定数据的字典。当线程退出并创建另一个线程时,线程标识符可以被回收。
-
_thread.
stack_size
([size])¶ 返回创建新线程时使用的线程堆栈大小。可选的 size 参数指定用于随后创建的线程的堆栈大小,并且必须为0(使用平台或配置的默认值)或至少为32,768(32 KiB)的正整数值。如果未指定 size,则使用0。如果不支持更改线程堆栈大小,则会引发
RuntimeError
。如果指定的堆栈大小无效,则会引发ValueError
并且堆栈大小未修改。 32 KiB是当前支持的最小堆栈大小值,以保证解释器本身有足够的堆栈空间。请注意,一些平台可能对堆栈大小的值有特殊限制,例如要求最小堆栈大小> 32 KiB或需要分配系统内存页大小的倍数 - 有关更多信息,请参阅平台文档(4 KiB页是常见的;使用4096的倍数作为堆栈大小是在没有更具体信息的情况下的建议方法)。可用性:Windows,具有POSIX线程的系统。
-
_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
语句使用,例如。:
import _thread
a_lock = _thread.allocate_lock()
with a_lock:
print("a_lock is locked while this executes")
注意事项:
线程与中断奇怪地交互:
KeyboardInterrupt
异常将被任意线程接收。 (当signal
模块可用时,中断总是到达主线程。)调用
sys.exit()
或提高SystemExit
异常等效于调用_thread.exit()
。不能在锁上中断
acquire()
方法 - 在获取锁之后将发生KeyboardInterrupt
异常。当主线程退出时,系统定义其他线程是否存活。在大多数系统上,它们被杀死,而不执行
try
...finally
子句或执行对象析构函数。当主线程退出时,它不进行任何常规的清理(除了
try
...finally
子句得到满足),并且标准I/O文件不被刷新。