標籤:建立 bsp pen 建議 操作 時間 focus containe 函數
Thread 模組
*註:在實際使用過程中不建議使用 thread 進行多線程編程,本文檔只為學習(或熟悉)多線程使用。
Thread 模組除了派生線程外,還提供了基本的同步資料結構,稱為鎖對象(lock object,也叫原語鎖、互斥鎖、互斥和二進位訊號量)。
常用線程函數以及 LockType 鎖對象的方法:
函數/方法 |
描述 |
thread 模組的函數 |
|
start_new_thread(function, args, kwargs=None) |
派生一個新的線程,使用給定的 args 和可選的 kwargs 來執行 function |
allocate_lock() |
分配 LockType 鎖對象 |
exit() |
給線程退出指令 |
LockType 鎖對象方法 |
|
acquire(wait=None) |
嘗試擷取鎖對象 |
locked() |
如果擷取了鎖對象則返回True,否則返回 Flase |
release() |
釋放鎖 |
使用 thread 模組的簡單例子,代碼如下(mtsleepA.py):
1 import thread 2 from time import sleep, ctime 3 ? 4 def loop0(): 5 print ‘start loop 0 at:‘, ctime() 6 sleep(4) 7 print ‘loop 0 Done at:‘, ctime() 8 ? 9 def loop1():10 print ‘start loop 1 at:‘, ctime()11 sleep(2)12 print ‘loop 1 Done at:‘, ctime()13 ?14 def main():15 print ‘starting at:‘, ctime()16 thread.start_new_thread(loop0, ())17 thread.start_new_thread(loop1, ())18 sleep(6)19 print ‘all DONE at:‘, ctime()20 ?21 if __name__ == ‘__main__‘:22 main()
輸出結果:
1 starting at: Sun Jul 22 21:38:00 20182 start loop 0 at: Sun Jul 22 21:38:00 20183 start loop 1 at: Sun Jul 22 21:38:00 20184 loop 1 Done at: Sun Jul 22 21:38:02 20185 loop 0 Done at: Sun Jul 22 21:38:04 20186 all DONE at: Sun Jul 22 21:38:06 2018
在這個指令碼的代碼中,增加了一個 sleep(6) 調用,為什麼要這麼做呢?這是因為如果我們沒有阻止主線程繼續執行,它將會繼續執行下一條語句,顯示“all done”然後退出,而 loop0() 和 loop1() 這兩個線程將直接終止。
使用線程和鎖的簡單例子,代碼如下(mtsleepB.py):
1 import thread 2 from time import sleep, ctime 3 ? 4 loops = [4,2] 5 ? 6 def loop(nloop, nsec, lock): 7 print ‘start loop‘, nloop, ‘at:‘, ctime() 8 sleep(nsec) 9 print ‘loop‘, nloop, ‘done at:‘, ctime()10 lock.release() # 釋放鎖11 ?12 def main():13 print ‘starting at:‘, ctime()14 locks = []15 nloops = range(len(loops))16 ?17 for i in nloops:18 lock = thread.allocate_lock() # 分配 LockType 對象19 lock.acquire() # 嘗試擷取鎖對象20 locks.append(lock)21 ?22 for i in nloops:23 thread.start_new_thread(loop, (i, loops[i], locks[i])) # 派生新線程24 25 for i in nloops:26 # 等待所有鎖釋放後退出迴圈繼續後面操作27 while locks[i].locked(): # 當擷取了鎖的時候為 True,所有的鎖都釋放後為 Flase28 pass29 ?30 print ‘all DONE at:‘, ctime()31 ?32 if __name__ == ‘__main__‘:33 main()
輸出結果為:
1 starting at: Sun Jul 22 22:25:45 20182 start loop 1 at:start loop Sun Jul 22 22:25:45 20183 0 at: Sun Jul 22 22:25:45 20184 loop 1 done at: Sun Jul 22 22:25:47 20185 loop 0 done at: Sun Jul 22 22:25:49 20186 all DONE at: Sun Jul 22 22:25:49 2018
main() 函數中鎖相關的主要流程(第一個 for 迴圈)解釋:
首先建立一個鎖列表,通過使用 thread.allocate_lock() 函數得到鎖對象;
再通過 acquire() 方法取得每個鎖(取得鎖的效果相當於“把鎖鎖上”);
把鎖鎖上後將它添加到鎖列表 locks 中;
為什麼不在上鎖的迴圈中啟動線程呢?
thread模組—Python多線程編程