"_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" 子句或執行物件的解構函
  式。
