# `_thread` --- 低階執行緒 API

這個模組提供了與多個執行緒（也稱為:dfn:輕量級行程 或 :dfn: 任務）一起工作的低階原始物件 --- 多個控制執行緒分享其全域資料空間。為了處理同步問題，也提供了簡單的鎖 (lock) 機制（也稱為:dfn:互斥鎖 或 二進位號誌）。 `threading` 模組提供了一個建立在這個模組之上的更易於使用和高階的執行緒 API。

在 3.7 版的變更: 這個模組之前是可選擇性的，但現在已經是可用的。

這個模組定義了以下的常數和函式：

exception _thread.error

  在執行緒相關的錯誤發生時引發。

  在 3.3 版的變更: 現在是內建例外 `RuntimeError` 的別名。

_thread.LockType

  這是鎖物件的型別。

_thread.start_new_thread(function, args[, kwargs])

  開始一個新的執行緒並回傳其識別字 (identifier) 。該執行緒執行帶有引數列表 args*（必須是一個 tuple（元組））的函式 *function。可選的 kwargs 引數指定一個關鍵字引數的字典。

  當函式回傳時，執行緒會靜默退出。

  當函式因未處理的例外終止時，將呼叫 `sys.unraisablehook()` 來處理該例外。鉤子引數的 object 屬性是 function。預設情況下，會列印堆疊跟蹤，然後執行緒退出（但其他執行緒會繼續運行）。

  當函式引發 `SystemExit` 例外時，它會被靜默忽略。

  引發一個 稽核事件 `_thread.start_new_thread`，帶有引數 `function`、`args` 和 `kwargs`。

  在 3.8 版的變更: 現在使用 `sys.unraisablehook()` 來處理未處理的例外。

_thread.interrupt_main(signum=signal.SIGINT, /)

  模擬一個訊號到達主執行緒的效果。執行緒可以使用此函式來中斷主執行緒，但無法保證中斷會立即發生。

  如果提供了 signum，則模擬指定的訊號編號。如果未提供 signum，則模擬 `signal.SIGINT` 訊號。

  如果給定的訊號在 Python 中未被處理（即設置為 `signal.SIG_DFL` 或 `signal.SIG_IGN`），此函式不做任何操作。

  在 3.10 版的變更: 新增了 signum 引數以自定義訊號編號。

  備註

  這並不會發出對應的訊號，而是安排呼叫相應的處理器（如果存在的話）。如果你想真正發出訊號，請使用 `signal.raise_signal()`。

_thread.exit()

  引發 `SystemExit` 例外。當未捕獲時，將導致執行緒靜默退出。

_thread.allocate_lock()

  回傳一個新的鎖物件。鎖物件的方法如下所述。初始狀況下鎖是解鎖狀態。

_thread.get_ident()

  回傳目前執行緒的「執行緒識別字」。這是一個非零的整數。它的值沒有直接的含義；它被用作一個 magic cookie，例如用於索引特定於執行緒的資料的字典。當執行緒退出並建立另一個執行緒時，執行緒識別字可能會被重複使用。

_thread.get_native_id()

  回傳由核心 (kernel) 分配的目前執行緒的原生整數執行緒 ID。這是一個非負整數。它的值可用於在整個系統中唯一標識此特定執行緒（直到執行緒終止後，該值可能被操作系統重新使用）。

  可用性: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX, DragonFlyBSD, GNU/kFreeBSD.

  在 3.8 版被加入.

  在 3.13 版的變更: 新增了對 GNU/kFreeBSD 的支援。

_thread.stack_size([size])

  回傳在建立新執行緒時使用的執行緒堆疊大小。可選的 size 引數指定了隨後建立的執行緒要使用的堆疊大小，必須是 0（使用平台或配置的預設值）或至少 32,768（32 KiB）的正整數值。如果未指定 size，則使用 0。如果不支持更改執行緒堆疊大小，則會引發 `RuntimeError` 錯誤。如果指定的堆疊大小無效，則會引發 `ValueError` 錯誤，並且堆疊大小不會被修改。目前，32 KiB 是保證解譯器本身具有足夠堆疊空間所支持的最小堆疊大小值。請注意，某些平台對於堆疊大小的值可能有特定的限制，例如要求最小堆疊大小 > 32 KiB，或要求按系統記憶體頁面大小的倍數進行分配。應參考平台文件以取得更多訊息（4 KiB 頁面是比較普遍的；在缺乏更具體訊息的情況下，建議使用 4096 的倍數作為堆疊大小）。

  可用性: Windows, pthreads.

  Unix 平台上支援 POSIX 執行緒。

_thread.TIMEOUT_MAX

  `Lock.acquire` 的 timeout 參數所允許的最大值。指定超過此值的 timeout 將引發 `OverflowError` 錯誤。

  在 3.2 版被加入.

鎖物件具有以下方法：

lock.acquire(blocking=True, timeout=-1)

  沒有任何可選引數時，此方法無條件地取得鎖，必要時會等待直到被另一個執行緒釋放（一次只能有一個執行緒取得鎖 --- 這正是鎖存在的原因）。

  如果存在 blocking 引數，則根據其值執行操作：如果為 False，只有在可以立即獲取鎖而無需等待的情況下才取得鎖，而如果為 True，則像上面一樣無條件地取得鎖。

  如果存在浮點數的 timeout 引數且為正值，則它指定了在回傳之前的最大等待時間（以秒為單位）。如果 timeout 引數為負值，則表示等待時間會無限期地等待。如果 blocking 為 False，則你無法指定 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 在執行這裡時被鎖定")

注意事項：

- 中斷總會跳到主執行緒（該執行緒將接收 `KeyboardInterrupt` 例外。）

- 呼叫 `sys.exit()` 函式或引發 `SystemExit` 例外等同於呼叫 `_thread.exit()` 函式。

- 鎖的 `acquire()` 方法是否可以中斷（如此一來 `KeyboardInterrupt` 例外會立即發生，而不是僅在取得鎖或操作逾時後）是取決於平台的。在 POSIX 上可以中斷，但在 Windows 上則不行。

- 當主執行緒退出時，其他執行緒是否保留是由系統決定的。在大多數系統上，它們將被終止，而不會執行 `try` ... `finally` 子句或執行物件的解構函式。