最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

python多線程互斥鎖與死鎖問題詳解

 更新時(shí)間:2022年01月27日 15:58:58   作者:陳小c  
大家好,本篇文章主要講的是python多線程互斥鎖與死鎖問題詳解,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下

一、多線程共享全局變量

代碼實(shí)現(xiàn)的功能:

創(chuàng)建work01與worker02函數(shù),對(duì)全局變量進(jìn)行加一操作創(chuàng)建main函數(shù),生成兩個(gè)線程,同時(shí)調(diào)用兩個(gè)函數(shù)

代碼如下:

import threading

result = 0  # 定義全局變量result
def work1(num):
    global result
    for i in range(num):
        result += 1
    print('------from work1-------', result)


def work2(num):
    global result
    for i in range(num):
        result += 1
    print('------from work2-------', result)


def main():
    print('--------begin--------', result)
    # 創(chuàng)建兩個(gè)線程
    t1 = threading.Thread(target=work1, args=(1000,))
    t2 = threading.Thread(target=work1, args=(1000,))
    t1.start()
    t2.start()

if __name__ == '__main__':
    main()

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

--------begin---------- 0
------from work1------- 1000
------from work1------- 2000

兩個(gè)線程之間共享了全局變量result,但是當(dāng)我們把range的數(shù)值調(diào)大一些,

    t1 = threading.Thread(target=work1, args=(1000000,))
    t2 = threading.Thread(target=work1, args=(1000000,))

我們?cè)賮砜匆幌陆Y(jié)果,這是為什么呢,我們往下看一下結(jié)果:

--------begin---------- 0
------from work1------- 1358452
------from work1------- 1696352

總結(jié):
在一個(gè)進(jìn)程內(nèi)的所有線程共享全局變量,很方便在多個(gè)線程間共享數(shù)據(jù)
缺點(diǎn)就是,線程是對(duì)全局變量隨意遂改可能造成多線程之間對(duì)全局變量的混亂(即線程非安全)

二、給線程加一把鎖鎖

假如當(dāng)前 g_num 值是100,當(dāng)線程1執(zhí)行第一步時(shí),cpu通過計(jì)算獲得結(jié)果101,并準(zhǔn)備把計(jì)算的結(jié)果101賦值給g_num,然后再傳值的過程中,線程2突然開始執(zhí)行了并且執(zhí)行了第一步,此時(shí)g_num的值仍未100,101還在傳遞的過程中,還沒成功賦值,線程2獲得計(jì)算結(jié)果101,并準(zhǔn)備傳遞給g_num,經(jīng)過一來一去這么一折騰,分明做了兩次加 1 操作,g_num結(jié)果卻是101,誤差就由此產(chǎn)生,往往循環(huán)次數(shù)越多,產(chǎn)生的誤差就越大,此時(shí)我們可以加一把鎖。

acquire() — 鎖定資源,此時(shí)資源是鎖定狀態(tài),其他線程無法修改鎖定的資源,直到等待鎖定的資源釋放之后才能操作;

release() — 釋放資源,也稱為解鎖操作,對(duì)鎖定的資源解鎖,解鎖之后其他線程可以對(duì)資源正常操作;

以上面的代碼為列子:想得到正確的結(jié)果,可以直接利用互斥鎖在全局變量 加1 之前 鎖定資源,然后在計(jì)算完成之后釋放資源,這樣就是一個(gè)完整的計(jì)算過程,至于應(yīng)該是哪個(gè)線程先執(zhí)行,無所謂,先到先得,憑本事說話….演示代碼如下:

# 開發(fā)時(shí)間:2022-01-27 12:59
import threading

result = 0  # 定義全局變量result
mutex = threading.Lock()

def work1(num):
    global result
    mutex.acquire()
    for i in range(num):
        result += 1
    print('------from work1-------', result)
    mutex.release()


def work2(num):
    global result
    mutex.acquire()
    for i in range(num):
        result += 1
    print('------from work2-------', result)
    mutex.release()


def main():
    print('--------begin----------', result)
    # 創(chuàng)建兩個(gè)線程
    t1 = threading.Thread(target=work1, args=(100000000,))
    t2 = threading.Thread(target=work1, args=(100000000,))
    t1.start()
    t2.start()


if __name__ == '__main__':
    main()

我們來看一下結(jié)果:

--------begin---------- 0
------from work1------- 100000000
------from work1------- 200000000

三、死鎖問題

1.單個(gè)互斥鎖的死鎖:

acquire()/release() 是成對(duì)出現(xiàn)的,互斥鎖對(duì)資源鎖定之后就一定要解鎖,否則資源會(huì)一直處于鎖定狀態(tài),其他線程無法修改;就好比上面的代碼,任何一個(gè)線程沒有釋放資源release(),程序就會(huì)一直處于阻塞狀態(tài)(在等待資源被釋放),不信你可以試一試~

2.多個(gè)互斥鎖的死鎖:

在同時(shí)操作多個(gè)互斥鎖的時(shí)候一定要格外小心,因?yàn)橐徊恍⌒木腿菀走M(jìn)入死循環(huán),假如有這樣一個(gè)場(chǎng)景:boss讓程序員一實(shí)現(xiàn)功能一的開發(fā),讓程序員二實(shí)現(xiàn)功能二的開發(fā),功能開發(fā)完成之后一起整合代碼!

# 導(dǎo)入線程threading模塊
import threading
# 導(dǎo)入線程time模塊
import time

# 創(chuàng)建互斥鎖
mutex_one = threading.Lock()
mutex_two = threading.Lock()


def programmer_thread1():
    mutex_one.acquire()
    print("我是程序員1,module1開發(fā)正式開始,程序一加鎖,程序二加鎖")
    time.sleep(2)

    # 此時(shí)會(huì)堵塞,因?yàn)檫@個(gè)mutex_two已經(jīng)被線程programmer_thread2搶先上鎖了,等待解鎖
    mutex_two.acquire()
    print("等待程序員2通知我合并代碼")
    mutex_two.release()
    print('程序員2開發(fā)完了,程序員1釋放第二把鎖')

    mutex_one.release()
    print('程序員1開發(fā)完了,程序員1釋放第一把鎖')


def programmer_thread2():
    mutex_two.acquire()
    print("我是程序員2,module2開發(fā)正式開始,程序二加鎖,程序一加鎖")
    time.sleep(2)
    # 此時(shí)會(huì)堵塞,因?yàn)檫@個(gè)mutex_one已經(jīng)被線程programmer_thread1搶先上鎖了,等待解鎖
    #mutex_two.release()
    mutex_one.acquire()
    print("等待程序員1通知我合并代碼")
    mutex_one.release()
    print('程序員2釋放第一把鎖')
   # mutex_two.release()
    print('程序員2釋放第二把鎖')


def main():
    t1 = threading.Thread(target=programmer_thread1)
    t2 = threading.Thread(target=programmer_thread2)

    # 啟動(dòng)線程
    t1.start()
    t2.start()
    # 阻塞函數(shù),等待線程結(jié)束
    t1.join()
    t2.join()
    # 整合代碼結(jié)束
    print("整合代碼結(jié)束 ")


if __name__ == "__main__":
    main()

分析下上面代碼:程序員1在等程序員2通知,程序員2在等程序員1通知,兩個(gè)線程都陷入阻塞中,因?yàn)閮蓚€(gè)線程都在等待對(duì)方解鎖,這就是死鎖!所以在開發(fā)中對(duì)于死鎖的問題還是需要多多注意!

總結(jié)

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

相關(guān)文章

最新評(píng)論

靖江市| 松潘县| 大港区| 都兰县| 西藏| 孝感市| 华池县| 封开县| 信丰县| 敦煌市| 赫章县| 石楼县| 格尔木市| 延寿县| 八宿县| 樟树市| 稷山县| 海门市| 怀安县| 措美县| 阳谷县| 鹤庆县| 客服| 枣阳市| 宣城市| 延长县| 长寿区| 成都市| 永修县| 织金县| 榆树市| 陆川县| 石城县| 宜春市| 嫩江县| 垫江县| 济宁市| 彰化县| 大丰市| 五华县| 万州区|