python進階之多線程對同一個全局變量的處理方法

發布時間: 2019-06-18 18:29:34 來源: 互聯網 欄目: python 點擊:

今天小編就為大家分享一篇python進階之多線程對同一個全局變量的處理方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

通常情況下:

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 = Thread(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,所以一般采用“通知”方式來做。

輪詢方式:

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進階之多線程對同一個全局變量的處理方法
本文地址: http://www.leskzw.tw/jiaoben/python/244061.html

如果認為本文對您有所幫助請贊助本站

支付寶掃一掃贊助微信掃一掃贊助

  • 支付寶掃一掃贊助
  • 微信掃一掃贊助
  • 支付寶先領紅包再贊助
    聲明:凡注明"本站原創"的所有文字圖片等資料,版權均屬編程客棧所有,歡迎轉載,但務請注明出處。
    python 利用for循環 保存多個圖像或者文件的實例Python文件循環寫入行時防止覆蓋的解決方法
    Top 广东好彩1中奖规则