Python 中多執行緒共享全域性變數的問題
阿新 • • 發佈:2022-04-13
寫在前面不得不看的一些P話:
Python 中多個執行緒之間是可以共享全域性變數的資料的。
但是,多執行緒共享全域性變數是會出問題的。
假設兩個執行緒 t1 和 t2 都要對全域性變數g_num (預設是0)進行加1運算,t1 和 t2 都各對g_num 加10次,g_num 的最終的結果應該為20。
但是由於多執行緒是同時操作,有可能出現下面情況:
在g_num=0時,t1 取得g_num=0。此時系統把 t1 排程為”sleeping”狀態,把t2轉換為”running”狀態,t2 也獲得 g_num=0。
然後 t2 對得到的值進行加1並賦給 g_num,使得g_num=1 。
接著系統又把 t2 排程為”sleeping”,把 t1 轉為”running”。執行緒t1又把它之前得到的0加1後賦值給g_num。
這樣導致雖然 t1 和 t2 都對g_num加1,但結果仍然是 g_num=1。
先看例子:
import threading import time g_num = 0 def work1(num): global g_num for i in range(num): g_num += 1 print("----in work1, g_num is %d---" % g_num) def work2(num): global g_num for i in range(num): g_num += 1 print("----in work2, g_num is %d---" % g_num) print("---執行緒建立之前g_num is %d---" % g_num) t1 = threading.Thread(target=work1, args=(100,)) t1.start() t2 = threading.Thread(target=work2, args=(100,)) t2.start() # 確保子執行緒都執行結束 while len(threading.enumerate()) != 1: time.sleep(1) print("2個執行緒對同一個全域性變數操作之後的最終結果是:%s" % g_num)
執行結果:
---執行緒建立之前g_num is 0---
----in work1, g_num is 100---
----in work2, g_num is 200---
2個執行緒對同一個全域性變數操作之後的最終結果是:200
乍一看,好像沒出什麼問題。那是因為資料太小了,我們現在把資料變大。
''' 遇到問題沒人解答?小編建立了一個Python學習交流QQ群:660193417 尋找有志同道合的小夥伴,互幫互助,群裡還有不錯的視訊學習教程和PDF電子書! ''' import threading import time g_num = 0 def work1(num): global g_num for i in range(num): g_num += 1 print("----in work1, g_num is %d---" % g_num) def work2(num): global g_num for i in range(num): g_num += 1 print("----in work2, g_num is %d---" % g_num) print("---執行緒建立之前g_num is %d---" % g_num) t1 = threading.Thread(target=work1, args=(1000000,)) t1.start() t2 = threading.Thread(target=work2, args=(1000000,)) t2.start() # 確保子執行緒都執行結束 while len(threading.enumerate()) != 1: time.sleep(1) print("2個執行緒對同一個全域性變數操作之後的最終結果是:%s" % g_num)
執行結果:
---執行緒建立之前g_num is 0---
----in work2, g_num is 1048576---
----in work1, g_num is 1155200---
2個執行緒對同一個全域性變數操作之後的最終結果是:1155200
數越大,出現問題的概率越大,而且資料的偏差也越大。
結論
如果多個執行緒同時對同一個全域性變數操作,會出現資源競爭問題,從而資料結果會不正確。