在之前,我們講過了,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
乍一看,好像沒出什么問題,那是因為資料太小了,我們現在把資料變大,
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
數越大,出現問題的概率越大,而且資料的偏差也越大,
結論
如果多個執行緒同時對同一個全域變數操作,會出現資源競爭問題,從而資料結果會不正確,
那能不能解決這個問題呢?
我們后面會講同步和互斥鎖的問題的,
通過同步和互斥鎖,我們可以解決 Python 中多執行緒共享全域變數時發生錯誤的問題,

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/124710.html
標籤:其他
