通常情況下:
from threading import thread
global_num = 0
def func1():
global global_num
for i in range(1000000):
global_num += 1
print('---------func1:global_num=%s--------'%global_num)
def func2():
global global_num
for i in range(1000000):
global_num += 1
print('--------fun2:global_num=%s'%global_num)
print('global_num=%s'%global_num)
lock = lock()
t1 = thread(target=func1)
t1.start()
t2 = www.cppcns.comthread(target=func2)
t2.start()
輸出結果:
global_num=0
---------func1:global_num=1492752--------
--------fun2:global_num=1515462
#由於多執行緒不像多程序一樣,每乙個程序都乙個獨立的資源塊,執行緒之間是共享主線程的乙個資源塊(程式設計客棧雖然這樣說不合適)
#這樣雖然方便了執行緒之間的資料傳遞,但是又會由於執行緒之間執行順序的不確定,導致最後的結果不是應該輸出的正確結果。
#例如下面的例程,如果沒有新增global_flag標誌全域性變數,就會出現,雖然邏輯上最後的結果是2000000(之所以選擇這麼大的乙個數,是因為可以更明顯的看出#這個問題),
#但是實際上並不是這個結果,而是乙個小於2000000的結果,但是不排出偶然會出現2000000,這是乙個極為理想的結果,這是為什麼呢?
#主要還是由於執行緒被cpu呼叫的順序不確定。具體來講就是當主線程建立出兩個子執行緒,分別是t1和t2,他們有分別指向func1()和func2()。
#在這兩個執行緒中的函式中,都有一句「global_num += 1」,在計算機內部cpu執行時,這一條語句實際上是兩個過程:第乙個過程是從記憶體中讀取global_num的值,完成加一操作,這個時候global_num的值還是原來的值;第二個過程是將求和的值付給global_num,這時候global_num的值才會更新。在程式執行過程中會出現這種
#情況:當cpu在執行執行緒t1中的語句到求和那條語句時,在執行完第乙個過程停了下來,將執行緒t1丟擲,轉而執行執行緒t2,當執行緒執行一段時間後也出現這中情況
#有轉而執行執行緒t1,這時,正好執行求和語句的第二個過程,完成最初的賦值,那麼這一段時間內的整個求和就等於沒做,所以出現這中最後結果不程式設計客棧是2000000的##情況
#解決這種情況可以利用新增乙個變數,利用「輪詢」的方式執行,但是這樣做的效率很低,而且還浪費cpu,所以一般採用「通知」方式來做。
輪詢www.cppcns.com方式:
from threading import thread
global_num = 0
global_flag = 0
def func1():
global global_num
global global_flag
if global_flag == 0:
for i in range(1000000):
global_num += 1
global_flag = 1
print('---------func1:global_num=%s--------'%global_num)
def func2():
global global_num
while true:
if 程式設計客棧global_flag != 0:
for i in range(1000000):
global_num += 1
break
print('--------fun2:global_num=%s'%global_num)
print('global_num=%s'%global_num)
t1 = thread(target=func1)
t1.start()
t2 = thread(target=func2)
t2.start()
執行結果:
global_num=0
---------func1:global_num=1000000--------
--------fun2:global_num=2000000
通知方式:
from threading import thread,lock
global_num = 0
def func1():
global global_num
for i in range(1000000):
lock.acquire()#兩個執行緒會最開始搶這個鎖,拿到鎖就會處於關鎖,執行後面的程式,其他執行緒執行處於監聽狀態,等待這個執行緒開鎖,再搶鎖
global_num += 1
lock.release()
print('---------func1:global_num=%s--------'%global_num)
def func2():
global global_num
for i in range(1000000):
lock.acquire()
global_num += 1
lock.release()
print('--------fun2:global_num=%s'%global_num)
print('global_num=%s'%global_num)
lock = lock()
t1 = thread(target=func1)
t1.start()
t2 = thread(target=func2)
t2.start()
輸出結果:
global_num=0
---------func1:global_num=1901175--------
--------fun2:global_num=2000000
本文標題: python高階之多執行緒對同乙個全域性變數的處理方法
本文位址:
Python之多執行緒
1 呼叫thread模組中的start new thread 函式來產生新執行緒 thread.start new thread function,args kwargs function 執行緒函式。args 傳遞給執行緒函式的引數,他必須是個tuple型別。kwargs 可選引數。2 使用thr...
python之多執行緒
學習了一下多執行緒 用到爬蟲裡面簡直爽歪歪呀 定義就很簡單,為了實現高併發,能夠同時在乙個指令碼下執行多個程式,節約時間 新增執行緒用到的 import threading as td def sum num1,num2 sum num1 num2 print sss sum def divided...
python之多執行緒
我們在商超買東西時,當只有乙個收銀台時,會導致排很長的隊。如果有多個收銀台同時工作的話,會大大提高效率。這是生活中的多執行緒,即多個執行緒同時工作。我們接下來用 案例講解多執行緒與單執行緒的區別。單執行緒即在程式執行過程中,按照一定的先後順序執行。多執行緒即多個事件同時發生。單執行緒 import ...