_thread --- 底層多線程 API?
該模塊提供了操作多個線程(也被稱為 輕量級進程 或 任務)的底層原語 —— 多個控制線程共享全局數(shù)據(jù)空間。為了處理同步問題,也提供了簡單的鎖機制(也稱為 互斥鎖 或 二進制信號)。threading 模塊基于該模塊提供了更易用的高級多線程 API。
在 3.7 版更改: 這個模塊曾經(jīng)為可選項,但現(xiàn)在總是可用。
這個模塊定義了以下常量和函數(shù):
-
exception
_thread.error? 發(fā)生線程相關錯誤時拋出。
在 3.3 版更改: 現(xiàn)在是內建異常
RuntimeError的別名。
-
_thread.LockType? 鎖對象的類型。
-
_thread.start_new_thread(function, args[, kwargs])? 啟動一個線程,并返回其標識符。線程會用 args 作為參數(shù)(必須是元組)執(zhí)行 function 函數(shù)。可選的 kwargs 參數(shù)使用字典來指定有名參數(shù)。當函數(shù)返回時,線程會靜默退出,當函數(shù)由于未處理的異常而中止時,會打印一條堆棧追蹤信息,然后該線程會退出(但其他線程還是會繼續(xù)運行)。
-
_thread.interrupt_main()? 模擬一個
signal.SIGINT信號到達主線程的效果。 線程可以使用這個函數(shù)來中斷主線程。如果 Python 沒有處理
signal.SIGINT(將它設為signal.SIG_DFL或signal.SIG_IGN),此函數(shù)將不做任何事。
-
_thread.exit()? 拋出
SystemExit異常。如果沒有捕獲的話,這個異常會使線程退出。
-
_thread.allocate_lock()? 返回一個新的鎖對象。鎖中的方法在后面描述。初始情況下鎖處于解鎖狀態(tài)。
-
_thread.get_ident()? 返回當前線程的 “線程標識符”。它是一個非零的整數(shù)。它的值沒有直接含義,主要是用作 magic cookie,比如作為含有線程相關數(shù)據(jù)的字典的索引。線程標識符可能會在線程退出,新線程創(chuàng)建時被復用。
-
_thread.stack_size([size])? 返回創(chuàng)建線程時使用的堆棧大小。可選參數(shù) size 指定之后新建的線程的堆棧大小,而且一定要是0(根據(jù)平臺或者默認配置)或者最小是32,768(32KiB)的一個正整數(shù)。如果 size 沒有指定,默認是0。如果不支持改變線程堆棧大小,會拋出
RuntimeError錯誤。如果指定的堆棧大小不合法,會拋出ValueError錯誤并且不會修改堆棧大小。32KiB是當前最小的能保證解釋器有足夠堆棧空間的堆棧大小。需要注意的是部分平臺對于堆棧大小會有特定的限制,例如要求大于32KiB的堆棧大小或者需要根據(jù)系統(tǒng)內存頁面的整數(shù)倍進行分配 - 應當查閱平臺文檔有關詳細信息(4KiB頁面比較普遍,在沒有更具體信息的情況下,建議的方法是使用4096的倍數(shù)作為堆棧大小)。適用于: Windows,具有 POSIX 線程的系統(tǒng)。
-
_thread.TIMEOUT_MAX? Lock.acquire()方法中 timeout 參數(shù)允許的最大值。傳入超過這個值的 timeout 會拋出OverflowError異常。3.2 新版功能.
鎖對象有以下方法:
-
lock.acquire(waitflag=1, timeout=-1)? 沒有任何可選參數(shù)時,該方法無條件申請獲得鎖,有必要的話會等待其他線程釋放鎖(同時只有一個線程能獲得鎖 —— 這正是鎖存在的原因)。
如果傳入了整型參數(shù) waitflag,具體的行為取決于傳入的值:如果是 0 的話,只會在能夠立刻獲取到鎖時才獲取,不會等待,如果是非零的話,會像之前提到的一樣,無條件獲取鎖。
如果傳入正浮點數(shù)參數(shù) timeout,相當于指定了返回之前等待得最大秒數(shù)。如果傳入負的 timeout,相當于無限期等待。如果 waitflag 是 0 的話,不能指定 timeout。
如果成功獲取到所會返回
True,否則返回False。在 3.2 版更改: 新的 timeout 形參。
在 3.2 版更改: 現(xiàn)在獲取鎖的操作可以被 POSIX 信號中斷。
-
lock.release()? 釋放鎖。鎖必須已經(jīng)被獲取過,但不一定是同一個線程獲取的。
-
lock.locked()? 返回鎖的狀態(tài):如果已被某個線程獲取,返回
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一場會在鎖獲取到之后發(fā)生。當主線程退出時,由系統(tǒng)決定其他線程是否存活。在大多數(shù)系統(tǒng)中,這些線程會直接被殺掉,不會執(zhí)行
try...finally語句,也不會執(zhí)行對象析構函數(shù)。當主線程退出時,不會進行正常的清理工作(除非使用了
try...finally語句),標準 I/O 文件也不會刷新。
