轉載或借鑒請注明轉自http://www.cnblogs.com/FG123/p/5068386.html 謝謝!
我們使用mutex(Python中的Lock類對象)來實現線程的同步:
lock.acquire() 相當於P操作,得到一個鎖,鎖定
lock.release()相當於V操作,釋放一個鎖,釋放
1 # -*- coding: cp936 -*- 2 import threading # Python主要通過標准庫中的threading包來實現多線程 3 import time 4 import os 5 6 7 def doChore(): #作為間隔 每次調用間隔0.5s 8 time.sleep(0.5) 9 10 11 def booth(tid): 12 global i 13 global lock 14 while True: 15 lock.acquire() # 得到一個鎖,鎖定 16 if i != 0: 17 i = i - 1 # 售票 售出一張減少一張 18 print(tid,':now left:',i) # 剩下的票數 19 doChore() 20 else: 21 print("Thread_id",tid," No more tickets") 22 os._exit(0) # 票售完 退出程序 23 lock.release() # 釋放鎖 24 doChore() 25 26 # Start of the main function 27 i= 15 # 初始化票數 28 lock = threading.Lock() # 創建鎖 29 30 # 總共設置了10個線程 31 for k in range(10): 32 new_thread = threading.Thread(target=booth,args=(k,)) # 創建線程; Python使用threading.Thread對象來代表線程 33 new_thread.start() # 調用start()方法啟動線程
-
我們在函數中使用global來聲明變量為全局變量,從而讓多線程共享i和lock (在C語言中,我們通過將變量放在所有函數外面來讓它成為全局變量)。如果不這么聲明,由於i和lock是不可變數據對象,它們將被當作一個局部變量。如果是可變數據對象的話,則不需要global聲明。我們甚至可以將可變數據對象作為參數來傳遞給線程函數。這些線程將共享這些可變數據對象。
- 在booth中使用了兩個doChore()函數。可以在未來改進程序,以便讓線程除了進行i=i-1之外,做更多的操作,比如打印剩余票數,找錢,或者喝口水之類的。第一個doChore()依然在Lock內部,所以可以安全地使用共享資源 (critical operations, 比如打印剩余票數)。第二個doChore()時,Lock已經被釋放,所以不能再去使用共享資源。這時候可以做一些不使用共享資源的操作 (non-critical operation, 比如找錢、喝水)。我故意讓doChore()等待了0.5秒,以代表這些額外的操作可能花費的時間。你可以定義的函數來代替doChore()。