16.3. thread — 多线程控制 — Python 文档

来自菜鸟教程
Python/docs/2.7/library/thread
跳转至:导航、​搜索

16.3. 线 — 多线程控制

笔记

thread 模块已在 Python 3 中重命名为 _thread2to3 工具将在将您的源代码转换为 Python 3 时自动调整导入; 但是,您应该考虑使用高级 threading 模块。


该模块提供用于处理多线程(也称为 轻量级进程任务 )的低级原语——多个控制线程共享其全局数据空间。 对于同步,提供了简单的锁(也称为 互斥锁二进制信号量 )。 threading 模块提供了一个更易于使用的高级线程 API,该 API 构建在该模块之上。

该模块是可选的。 它在 Windows、Linux、SGI IRIX、Solaris 2.x 以及具有 POSIX 线程(又名 “pthread”)实现。 对于缺少 thread 模块的系统,可以使用 dummy_thread 模块。 它复制了这个模块的接口,可以用作替代品。

它定义了以下常量和函数:

exception thread.error
引发线程特定的错误。
thread.LockType
这是锁对象的类型。
thread.start_new_thread(function, args[, kwargs])
启动一个新线程并返回其标识符。 线程使用参数列表 args(必须是元组)执行函数 function。 可选的 kwargs 参数指定关键字参数的字典。 当函数返回时,线程默默退出。 当函数因未处理的异常而终止时,会打印堆栈跟踪,然后线程退出(但其他线程继续运行)。
thread.interrupt_main()

在主线程中引发 KeyboardInterrupt 异常。 子线程可以使用这个函数来中断主线程。

2.3 版中的新功能。

thread.exit()
引发 SystemExit 异常。 如果没有被捕获,这将导致线程静默退出。
thread.allocate_lock()
返回一个新的锁对象。 下面描述了锁的方法。 锁最初是解锁的。
thread.get_ident()
返回当前线程的“线程标识符”。 这是一个非零整数。 它的价值没有直接的意义; 它旨在用作魔术饼干,例如 索引线程特定数据的字典。 当一个线程退出并创建另一个线程时,线程标识符可能会被回收。
thread.stack_size([size])

返回创建新线程时使用的线程堆栈大小。 可选的 size 参数指定用于后续创建的线程的堆栈大小,并且必须为 0(使用平台或配置的默认值)或至少为 32,768 (32kB) 的正整数值。 如果未指定 size,则使用 0。 如果不支持更改线程堆栈大小,则会引发 错误 异常。 如果指定的堆栈大小无效,则会引发 ValueError 并且堆栈大小未修改。 32kB 是当前支持的最小堆栈大小值,以保证解释器本身有足够的堆栈空间。 请注意,某些平台可能对堆栈大小的值有特定限制,例如要求最小堆栈大小 > 32kB 或要求以系统内存页面大小的倍数进行分配 - 应参考平台文档以获取更多信息(4kB 页面很常见) ;如果没有更具体的信息,建议使用 4096 的倍数作为堆栈大小)。 可用性:Windows,具有 POSIX 线程的系统。

2.5 版中的新功能。

锁对象有以下方法:

lock.acquire([waitflag])
如果没有可选参数,此方法将无条件地获取锁,如有必要,等待它被另一个线程释放(一次只有一个线程可以获取锁——这就是它们存在的原因)。 如果存在整数 waitflag 参数,则操作取决于其值:如果为零,则仅在无需等待即可立即获取时才获取锁,如果不为零,则获取锁像以前一样无条件。 获取锁成功返回值为True,否则返回值为False
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 异常将在获取锁后发生。

  • 当主线程退出时,其他线程是否存活由系统定义。 在使用本机线程实现的 SGI IRIX 上,它们仍然存在。 在大多数其他系统上,它们在不执行 try ... finally 子句或执行对象析构函数的情况下被杀死。

  • 当主线程退出时,它不会执行任何通常的清理(除了 try ... finally 子句被遵守),并且标准 I/O 文件不会被刷新。