# 17.9. `_thread` — Low-level threading API

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

模块是可选的。它在Windows，Linux，SGI IRIX，Solaris 2.x以及具有POSIX线程（也称为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参数，则操作取决于其值：如果它为零，则仅在无需等待即可立即获取锁时才获取锁，而如果非零，则锁是无条件获得。

  如果浮点超时参数存在且为正，则它指定返回前的最大等待时间（以秒为单位）。负数超时参数指定无界等待。如果waitflag为零，则不能指定超时。

  如果成功获取锁，则返回值为`True`，如果未成功，则返回`False`。

  在版本3.2中更改： 超时参数是新的。

  在版本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文件不冲洗。