亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

python多線程互斥鎖與死鎖

 更新時(shí)間:2022年02月10日 12:07:17   作者:侯小啾 ?  
這篇文章主要介紹了python多線程互斥鎖與死鎖,多線程間的資源競(jìng)爭(zhēng)下文我們就以task1(),task2()兩個(gè)函數(shù)為例,分別將對(duì)全局變量num加一重復(fù)一千萬次循環(huán),具有一定得參考價(jià)值,需要的小伙伴可以參考一下

一、多線程間的資源競(jìng)爭(zhēng)

以下列task1(),task2()兩個(gè)函數(shù)為例,分別將對(duì)全局變量num加一重復(fù)一千萬次循環(huán)(數(shù)據(jù)大一些,太小的話執(zhí)行太快,達(dá)不到驗(yàn)證的效果)。

import threading
import time

num = 0


def task1(nums):
? ? global num
? ? for i in range(nums):
? ? ? ? num += 1

? ? print("task1---num=%d" % num)


def task2(nums):
? ? global num
? ? for i in range(nums):
? ? ? ? num += 1
? ? print("task2---num=%d" % num)


if __name__ == '__main__':
? ? nums = 10000000
? ? t1 = threading.Thread(target=task1, args=(nums,))
? ? t2 = threading.Thread(target=task2, args=(nums,))

? ? t1.start()
? ? t2.start()
? ? # 因?yàn)橹骶€程不會(huì)等子線程執(zhí)行完就會(huì)執(zhí)行,所以這里延遲五秒,確保最后執(zhí)行。
? ? time.sleep(5)
? ? print("main----num=%d" % num)

程序運(yùn)行結(jié)果:

如圖,輸出結(jié)果比較混亂,既沒有一千萬,最終結(jié)果也不是二千萬。因?yàn)槎嗑€程運(yùn)行時(shí)出現(xiàn)了資源競(jìng)爭(zhēng),即可以理解為,每個(gè)函數(shù)運(yùn)行的時(shí)間都不確定,且互相影響,
如從初始值0開始,假設(shè)t1的線程先執(zhí)行,執(zhí)行到+1后,此時(shí)的num=1還未存儲(chǔ),然后即被叫停,t2開始執(zhí)行,去獲取num,獲取到的num等于初始值0,然后其執(zhí)行了+1并存儲(chǔ),存儲(chǔ)后num=1,然后t2停止t1繼續(xù),再次存儲(chǔ)num=1。即加了兩次1,但是num還是只等于1。
因?yàn)閠1和t2誰來運(yùn)行的分配是完全隨機(jī)的,所以最后加了兩千萬次1后值是小于2000萬的。

解決此類問題,可以使用到互斥鎖 。

二、互斥鎖

  • 某個(gè)線程要更改共享數(shù)據(jù)時(shí),先將其鎖定,此時(shí)資源的狀態(tài)為"鎖定",其他線程不能改變,只到該線程釋放資源,將資源的狀態(tài)變成"非鎖定",其他的線程才能再次鎖定該資源。
  • 互斥鎖保證了每次只有一個(gè)線程進(jìn)行寫入操作,從而保證了多線程情況下數(shù)據(jù)的正確性。

1.互斥鎖示例

創(chuàng)建一把鎖:

mutex = threading.Lock()
mutex.acquire() # 上鎖
xxxx鎖定的內(nèi)容xxxxx
mutex.release() # 解鎖

將互斥鎖加入到上邊的代碼中如下,則問題得到了解決。

import threading
import time

num = 0


def task1(nums):
? ? global num
? ? mutex.acquire()
? ? for i in range(nums):
? ? ? ? num += 1
? ? mutex.release()
? ? print("task1---num=%d" % num)


def task2(nums):
? ? global num
? ? mutex.acquire()
? ? for i in range(nums):
? ? ? ? num += 1
? ? mutex.release()
? ? print("task2---num=%d" % num)


if __name__ == '__main__':
? ? nums = 10000000
? ? mutex = threading.Lock()
? ? t1 = threading.Thread(target=task1, args=(nums,))
? ? t2 = threading.Thread(target=task2, args=(nums,))

? ? t1.start()
? ? t2.start()
? ? # 因?yàn)橹骶€程不會(huì)等子線程執(zhí)行完就會(huì)執(zhí)行,所以這里延遲五秒,確保最后執(zhí)行。
? ? time.sleep(5)
? ? print("main----num=%d" % num)

程序運(yùn)行結(jié)果:

2.可重入鎖與不可重入鎖

threading.Lock()上的是不可重入鎖,即一次只能加一把鎖,不能加多把。

threading.Lock()

如果需要同時(shí)加多把所,則需加入不可重入鎖

創(chuàng)建一把可重入鎖:

mutex = threading.RLock()
mutex.acquire() # 上鎖
mutex.acquire() # 再上鎖
xxxx鎖定的內(nèi)容xxxxx
mutex.release() # 解鎖
mutex.release() # 再解鎖

其中上鎖和解鎖的次數(shù)必須保持一致。

三、死鎖

在線程間共享多個(gè)資源的時(shí)候,如果兩個(gè)線程分別占有一部分資源并且同時(shí)等待對(duì)方的資源,就會(huì)程序堵塞,造成死鎖。

  • 死鎖一般用不到。
  • 程序設(shè)計(jì)要盡量避免。

到此這篇關(guān)于python多線程互斥鎖與死鎖的文章就介紹到這了,更多相關(guān)python多線程互斥鎖與死鎖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論