_thread
--- 底層多線(xiàn)程 API?
該模塊提供了操作多個(gè)線(xiàn)程(也被稱(chēng)為 輕量級進(jìn)程 或 任務(wù))的底層原語(yǔ) —— 多個(gè)控制線(xiàn)程共享全局數據空間。為了處理同步問(wèn)題,也提供了簡(jiǎn)單的鎖機制(也稱(chēng)為 互斥鎖 或 二進(jìn)制信號)。threading
模塊基于該模塊提供了更易用的高級多線(xiàn)程 API。
在 3.7 版更改: 這個(gè)模塊曾經(jīng)為可選項,但現在總是可用。
這個(gè)模塊定義了以下常量和函數:
- exception _thread.error?
發(fā)生線(xiàn)程相關(guān)錯誤時(shí)拋出。
在 3.3 版更改: 現在是內建異常
RuntimeError
的別名。
- _thread.LockType?
鎖對象的類(lèi)型。
- _thread.start_new_thread(function, args[, kwargs])?
開(kāi)啟一個(gè)新線(xiàn)程并返回其標識。 線(xiàn)程執行函數 function 并附帶參數列表 args (必須是元組)。 可選的 kwargs 參數指定一個(gè)關(guān)鍵字參數字典。
當函數返回時(shí),線(xiàn)程會(huì )靜默地退出。
當函數因某個(gè)未處理異常而終結時(shí),
sys.unraisablehook()
會(huì )被調用以處理異常。 鉤子參數的 object 屬性為 function。 在默認情況下,會(huì )打印堆?;厮萑缓笤摼€(xiàn)程將退出(但其他線(xiàn)程會(huì )繼續運行)。當函數引發(fā)
SystemExit
異常時(shí),它會(huì )被靜默地忽略。在 3.8 版更改: 現在會(huì )使用
sys.unraisablehook()
來(lái)處理未處理的異常。
- _thread.interrupt_main(signum=signal.SIGINT, /)?
模擬一個(gè)信號到達主線(xiàn)程的效果。 線(xiàn)程可使用此函數來(lái)打斷主線(xiàn)程,雖然并不保證打斷將立即發(fā)生。
如果給出 signum,則表示要模擬的信號的編號。 如果未給出 signum,則將模擬
signal.SIGINT
。如果 Python 沒(méi)有處理給定的信號 (它被設為
signal.SIG_DFL
或signal.SIG_IGN
),此函數將不做任何操作。在 3.10 版更改: 添加了 signum 參數來(lái)定制信號的編號。
備注
這并不會(huì )發(fā)出對應的信號而是將一個(gè)調用排入關(guān)聯(lián)處理句柄的計劃任務(wù)(如果句柄存在的話(huà))。 如果你想要真的發(fā)出信號,請使用
signal.raise_signal()
。
- _thread.exit()?
拋出
SystemExit
異常。如果沒(méi)有捕獲的話(huà),這個(gè)異常會(huì )使線(xiàn)程退出。
- _thread.allocate_lock()?
返回一個(gè)新的鎖對象。鎖中的方法在后面描述。初始情況下鎖處于解鎖狀態(tài)。
- _thread.get_ident()?
返回當前線(xiàn)程的 “線(xiàn)程標識符”。它是一個(gè)非零的整數。它的值沒(méi)有直接含義,主要是用作 magic cookie,比如作為含有線(xiàn)程相關(guān)數據的字典的索引。線(xiàn)程標識符可能會(huì )在線(xiàn)程退出,新線(xiàn)程創(chuàng )建時(shí)被復用。
- _thread.get_native_id()?
返回內核分配給當前線(xiàn)程的原生集成線(xiàn)程 ID。 這是一個(gè)非負整數。 它的值可被用來(lái)在整個(gè)系統中唯一地標識這個(gè)特定線(xiàn)程(直到線(xiàn)程終結,在那之后該值可能會(huì )被 OS 回收再利用)。
Availability: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX, DragonFlyBSD.
3.8 新版功能.
- _thread.stack_size([size])?
返回創(chuàng )建線(xiàn)程時(shí)使用的堆棧大小??蛇x參數 size 指定之后新建的線(xiàn)程的堆棧大小,而且一定要是0(根據平臺或者默認配置)或者最小是32,768(32KiB)的一個(gè)正整數。如果 size 沒(méi)有指定,默認是0。如果不支持改變線(xiàn)程堆棧大小,會(huì )拋出
RuntimeError
錯誤。如果指定的堆棧大小不合法,會(huì )拋出ValueError
錯誤并且不會(huì )修改堆棧大小。32KiB是當前最小的能保證解釋器有足夠堆??臻g的堆棧大小。需要注意的是部分平臺對于堆棧大小會(huì )有特定的限制,例如要求大于32KiB的堆棧大小或者需要根據系統內存頁(yè)面的整數倍進(jìn)行分配 - 應當查閱平臺文檔有關(guān)詳細信息(4KiB頁(yè)面比較普遍,在沒(méi)有更具體信息的情況下,建議的方法是使用4096的倍數作為堆棧大?。?。適用于: Windows,具有 POSIX 線(xiàn)程的系統。
- _thread.TIMEOUT_MAX?
Lock.acquire()
方法中 timeout 參數允許的最大值。傳入超過(guò)這個(gè)值的 timeout 會(huì )拋出OverflowError
異常。3.2 新版功能.
鎖對象有以下方法:
- lock.acquire(waitflag=1, timeout=- 1)?
沒(méi)有任何可選參數時(shí),該方法無(wú)條件申請獲得鎖,有必要的話(huà)會(huì )等待其他線(xiàn)程釋放鎖(同時(shí)只有一個(gè)線(xiàn)程能獲得鎖 —— 這正是鎖存在的原因)。
如果傳入了整型參數 waitflag,具體的行為取決于傳入的值:如果是 0 的話(huà),只會(huì )在能夠立刻獲取到鎖時(shí)才獲取,不會(huì )等待,如果是非零的話(huà),會(huì )像之前提到的一樣,無(wú)條件獲取鎖。
如果傳入正浮點(diǎn)數參數 timeout,相當于指定了返回之前等待得最大秒數。如果傳入負的 timeout,相當于無(wú)限期等待。如果 waitflag 是 0 的話(huà),不能指定 timeout。
如果成功獲取到所會(huì )返回
True
,否則返回False
。在 3.2 版更改: 新的 timeout 形參。
在 3.2 版更改: 現在獲取鎖的操作可以被 POSIX 信號中斷。
- lock.release()?
釋放鎖。鎖必須已經(jīng)被獲取過(guò),但不一定是同一個(gè)線(xiàn)程獲取的。
- lock.locked()?
返回鎖的狀態(tài):如果已被某個(gè)線(xiàn)程獲取,返回
True
,否則返回False
。
除了這些方法之外,鎖對象也可以通過(guò) with
語(yǔ)句使用,例如:
import _thread
a_lock = _thread.allocate_lock()
with a_lock:
print("a_lock is locked while this executes")
注意事項:
線(xiàn)程與中斷奇怪地交互:
KeyboardInterrupt
異??赡軙?huì )被任意一個(gè)線(xiàn)程捕獲。(如果signal
模塊可用的話(huà),中斷總是會(huì )進(jìn)入主線(xiàn)程。)調用
sys.exit()
或是拋出SystemExit
異常等效于調用_thread.exit()
。不可能中斷鎖的
acquire()
方法 ——KeyboardInterrupt
一場(chǎng)會(huì )在鎖獲取到之后發(fā)生。當主線(xiàn)程退出時(shí),由系統決定其他線(xiàn)程是否存活。在大多數系統中,這些線(xiàn)程會(huì )直接被殺掉,不會(huì )執行
try
...finally
語(yǔ)句,也不會(huì )執行對象析構函數。當主線(xiàn)程退出時(shí),不會(huì )進(jìn)行正常的清理工作(除非使用了
try
...finally
語(yǔ)句),標準 I/O 文件也不會(huì )刷新。