thread模塊—Python多線程編程

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):app

 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 2018
2 start loop 0 at: Sun Jul 22 21:38:00 2018
3  start loop 1 at: Sun Jul 22 21:38:00 2018
4 loop 1 Done at: Sun Jul 22 21:38:02 2018
5 loop 0 Done at: Sun Jul 22 21:38:04 2018
6 all DONE at: Sun Jul 22 21:38:06 2018

 

在這個腳本的代碼中,增長了一個 sleep(6) 調用,爲何要這麼作呢?這是由於若是咱們沒有阻止主線程繼續執行,它將會繼續執行下一條語句,顯示「all done」而後退出,而 loop0() 和 loop1() 這兩個線程將直接終止。oop

 


使用線程和鎖的簡單例子,代碼以下(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,全部的鎖都釋放後爲 Flase
28             pass
29 30     print 'all DONE at:', ctime()
31 32 if __name__ == '__main__':
33     main()

 

輸出結果爲:
1 starting at: Sun Jul 22 22:25:45 2018
2 start loop 1 at:start loop Sun Jul 22 22:25:45 2018
3  0 at: Sun Jul 22 22:25:45 2018
4 loop 1 done at: Sun Jul 22 22:25:47 2018
5 loop 0 done at: Sun Jul 22 22:25:49 2018
6 all DONE at: Sun Jul 22 22:25:49 2018

 

main() 函數中鎖相關的主要流程(第一個 for 循環)解釋:ui

  1. 首先建立一個鎖列表,經過使用 thread.allocate_lock() 函數獲得鎖對象;spa

  2. 再經過 acquire() 方法取得每一個鎖(取得鎖的效果至關於「把鎖鎖上」);線程

  3. 把鎖鎖上後將它添加到鎖列表 locks 中;

爲何不在上鎖的循環中啓動線程呢?

  • 第一,想要同步線程,讓全部的線程最後同時都完成;

  • 第二,獲取鎖須要花費一點時間,避免線程執行的太快,在獲取鎖以前線程就執行結束。

相關文章
相關標籤/搜索