一、共用變數 共用變數:當多個線程訪問同一個變數的時候。會產生共用變數的問題。 例子: 正如上面的結果可以看出:並不是我們期望的0,而是-286705,這就是因為我們共用變數了,同時對變數進行了操作,程式並不是原子的。 2.解決方案:使用“鎖”,“信號燈” (1)鎖lock:是一個標誌,表示一個線程 ...
一、共用變數
共用變數:當多個線程訪問同一個變數的時候。會產生共用變數的問題。
例子:
import threading sum = 0 loopSum = 1000000 def myAdd(): global sum, loopSum for i in range(1,loopSum): sum += 1 def myMinu(): global sum, loopSum for i in range(1,loopSum): sum -= 1 if __name__ == "__main__": print("Dont,,,,,,,{0}".format(sum)) t1 = threading.Thread(target=myAdd,args=()) t2 = threading.Thread(target=myMinu,args=()) t1.start() t2.start() t1.join() t2.join() print("Done,,,,,,{0}".format(sum))
正如上面的結果可以看出:並不是我們期望的0,而是-286705,這就是因為我們共用變數了,同時對變數進行了操作,程式並不是原子的。
2.解決方案:使用“鎖”,“信號燈”
(1)鎖lock:是一個標誌,表示一個線程在占用一些資源。
使用方式:先上鎖,然後使用共用資源,放心的使用,最後再釋放鎖,即釋放了這個變數。
鎖哪個:哪個資源需要共用,那麼就鎖誰
import threading sum = 0 loopSum = 1000000 lock = threading.Lock() #先生成一個鎖的實例 def myAdd(): global sum, loopSum for i in range(1,loopSum): lock.acquire()#這裡申請了一把鎖 sum += 1 lock.release()#註意千萬不要忘了釋放鎖 def myMinu(): global sum, loopSum for i in range(1,loopSum): lock.acquire() sum -= 1 lock.release() if __name__ == "__main__": print("Done,,,,,,,{0}".format(sum)) t1 = threading.Thread(target=myAdd,args=()) t2 = threading.Thread(target=myMinu,args=()) t1.start() t2.start() t1.join() t2.join() print("Done,,,,,,{0}".format(sum))
正如我們所預料的加減的順序無所謂,但最後是零和游戲,但是上面的那個例子,都也是加減順序無所謂,但是有一點要知道會存在同時對變數的記憶體使用的情況,這就存在記憶體被錯寫的風險,所以最後結果不對,上面的不是零和游戲。
(2)線程的安全問題:
如果一個資源、變數,他對於多線程來講,不用加鎖,也不會引起任何問題,則稱為線程安全;線程不安全的變數類型:list\set\dict;線程安全的變數類型:queue
二、源碼
d25_1_shared_variable_and_lock.py
https://github.com/ruigege66/Python_learning/blob/master/d25_1_shared_variable_and_lock.py
2.CSDN:https://blog.csdn.net/weixin_44630050(心悅君兮君不知-睿)
3.博客園:https://www.cnblogs.com/ruigege0000/
4.歡迎關註微信公眾號:傅里葉變換,後臺回覆”禮包“,獲取大數據學習資料