<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當(dāng)前位置: 首頁 - 科技 - 知識百科 - 正文

        舉例講解Python中的死鎖、可重入鎖和互斥鎖

        來源:懂視網(wǎng) 責(zé)編:小采 時間:2020-11-27 14:41:58
        文檔

        舉例講解Python中的死鎖、可重入鎖和互斥鎖

        舉例講解Python中的死鎖、可重入鎖和互斥鎖:一、死鎖 簡單來說,死鎖是一個資源被多次調(diào)用,而多次調(diào)用方都未能釋放該資源就會造成死鎖,這里結(jié)合例子說明下兩種常見的死鎖情況。 1、迭代死鎖 該情況是一個線程迭代請求同一個資源,直接就會造成死鎖: import threading import time
        推薦度:
        導(dǎo)讀舉例講解Python中的死鎖、可重入鎖和互斥鎖:一、死鎖 簡單來說,死鎖是一個資源被多次調(diào)用,而多次調(diào)用方都未能釋放該資源就會造成死鎖,這里結(jié)合例子說明下兩種常見的死鎖情況。 1、迭代死鎖 該情況是一個線程迭代請求同一個資源,直接就會造成死鎖: import threading import time

        一、死鎖

        簡單來說,死鎖是一個資源被多次調(diào)用,而多次調(diào)用方都未能釋放該資源就會造成死鎖,這里結(jié)合例子說明下兩種常見的死鎖情況。

        1、迭代死鎖

        該情況是一個線程“迭代”請求同一個資源,直接就會造成死鎖:

        import threading
        import time
        class MyThread(threading.Thread):
         def run(self):
         global num
         time.sleep(1)
         if mutex.acquire(1):
         num = num+1
         msg = self.name+' set num to '+str(num)
         print msg
         mutex.acquire()
         mutex.release()
         mutex.release()
        num = 0
        mutex = threading.Lock()
        def test():
         for i in range(5):
         t = MyThread()
         t.start()
        if __name__ == '__main__':
         test()
        

        上例中,在run函數(shù)的if判斷中第一次請求資源,請求后還未 release ,再次acquire,最終無法釋放,造成死鎖。這里例子中通過將print下面的兩行注釋掉就可以正常執(zhí)行了 ,除此之外也可以通過可重入鎖解決,后面會提到。

        2、互相調(diào)用死鎖

        上例中的死鎖是在同一個def函數(shù)內(nèi)多次調(diào)用造成的,另一種情況是兩個函數(shù)中都會調(diào)用相同的資源,互相等待對方結(jié)束的情況。如果兩個線程分別占有一部分資源并且同時等待對方的資源,就會造成死鎖。

        import threading
        import time
        class MyThread(threading.Thread):
         def do1(self):
         global resA, resB
         if mutexA.acquire():
         msg = self.name+' got resA'
         print msg
         if mutexB.acquire(1):
         msg = self.name+' got resB'
         print msg
         mutexB.release()
         mutexA.release()
         def do2(self):
         global resA, resB
         if mutexB.acquire():
         msg = self.name+' got resB'
         print msg
         if mutexA.acquire(1):
         msg = self.name+' got resA'
         print msg
         mutexA.release()
         mutexB.release()
         def run(self):
         self.do1()
         self.do2()
        resA = 0
        resB = 0
        mutexA = threading.Lock()
        mutexB = threading.Lock()
        def test():
         for i in range(5):
         t = MyThread()
         t.start()
        if __name__ == '__main__':
         test()
        

        這個死鎖的示例稍微有點(diǎn)復(fù)雜。具體可以理下。

        二、可重入鎖

        為了支持在同一線程中多次請求同一資源,python提供了“可重入鎖”:threading.RLock。RLock內(nèi)部維護(hù)著一個Lock和一個counter變量,counter記錄了acquire的次數(shù),從而使得資源可以被多次require。直到一個線程所有的acquire都被release,其他的線程才能獲得資源。這里以例1為例,如果使用RLock代替Lock,則不會發(fā)生死鎖:

        import threading
        import time
        class MyThread(threading.Thread):
         def run(self):
         global num
         time.sleep(1)
         if mutex.acquire(1):
         num = num+1
         msg = self.name+' set num to '+str(num)
         print msg
         mutex.acquire()
         mutex.release()
         mutex.release()
        num = 0
        mutex = threading.RLock()
        def test():
         for i in range(5):
         t = MyThread()
         t.start()
        if __name__ == '__main__':
         test()
        

        和上面那個例子的不同之處在于threading.Lock()換成了threading.RLock() 。

        三、互斥鎖
        python threading模塊有兩類鎖:互斥鎖(threading.Lock )和可重用鎖(threading.RLock)。兩者的用法基本相同,具體如下:

        lock = threading.Lock()
        lock.acquire()
        dosomething……
        lock.release()
        

        RLock的用法是將threading.Lock()修改為threading.RLock()。便于理解,先來段代碼:

        [root@361way lock]# cat lock1.py
        

        #!/usr/bin/env python
        # coding=utf-8
        import threading # 導(dǎo)入threading模塊
        import time # 導(dǎo)入time模塊
        class mythread(threading.Thread): # 通過繼承創(chuàng)建類
         def __init__(self,threadname): # 初始化方法
         # 調(diào)用父類的初始化方法
         threading.Thread.__init__(self,name = threadname)
         def run(self): # 重載run方法
         global x # 使用global表明x為全局變量
         for i in range(3):
         x = x + 1
         time.sleep(5) # 調(diào)用sleep函數(shù),讓線程休眠5秒
         print x
        tl = [] # 定義列表
        for i in range(10):
         t = mythread(str(i)) # 類實(shí)例化
         tl.append(t) # 將類對象添加到列表中
        x=0 # 將x賦值為0
        for i in tl:
         i.start() 
        

        這里執(zhí)行的結(jié)果和想想的不同,結(jié)果如下:

        [root@361way lock]# python lock1.py
        

        30
        30
        30
        30
        30
        30
        30
        30
        30
        30
        

        為什么結(jié)果都是30呢?關(guān)鍵在于global 行和 time.sleep行。

        1、由于x是一個全局變量,所以每次循環(huán)后 x 的值都是執(zhí)行后的結(jié)果值;

        2、由于該代碼是多線程的操作,所以在sleep 等待的時候,之前已經(jīng)執(zhí)行完成的線程會在這等待,而后續(xù)的進(jìn)程在等待的5秒這段時間也執(zhí)行完成 ,等待print。同樣由于global 的原理,x被重新斌值。所以打印出的結(jié)果全是30 ;

        3、便于理解,可以嘗試將sleep等注釋,你再看下結(jié)果,就會發(fā)現(xiàn)有不同。

        在實(shí)際應(yīng)用中,如抓取程序等,也會出現(xiàn)類似于sleep等待的情況。在前后調(diào)用有順序或打印有輸出的時候,就會現(xiàn)并發(fā)競爭,造成結(jié)果或輸出紊亂。這里就引入了鎖的概念,上面的代碼修改下,如下:

        [root@361way lock]# cat lock2.py
        

        #!/usr/bin/env python
        # coding=utf-8
        import threading # 導(dǎo)入threading模塊
        import time # 導(dǎo)入time模塊
        class mythread(threading.Thread): # 通過繼承創(chuàng)建類
         def __init__(self,threadname): # 初始化方法
         threading.Thread.__init__(self,name = threadname)
         def run(self): # 重載run方法
         global x # 使用global表明x為全局變量
         lock.acquire() # 調(diào)用lock的acquire方法
         for i in range(3):
         x = x + 1
         time.sleep(5) # 調(diào)用sleep函數(shù),讓線程休眠5秒
         print x
         lock.release() # 調(diào)用lock的release方法
        lock = threading.Lock() # 類實(shí)例化
        tl = [] # 定義列表
        for i in range(10):
         t = mythread(str(i)) # 類實(shí)例化
         tl.append(t) # 將類對象添加到列表中
        x=0 # 將x賦值為0
        for i in tl:
         i.start() # 依次運(yùn)行線程
        

        執(zhí)行的結(jié)果如下:

        [root@361way lock]# python lock2.py
        

        3
        6
        9
        12
        15
        18
        21
        24
        27
        30
        

        加鎖的結(jié)果會造成阻塞,而且會造成開鎖大。會根據(jù)順序由并發(fā)的多線程按順序輸出,如果后面的線程執(zhí)行過快,需要等待前面的進(jìn)程結(jié)束后其才能結(jié)束 --- 寫的貌似有點(diǎn)像隊(duì)列的概念了 ,不過在加鎖的很多場景下確實(shí)可以通過隊(duì)列去解決。

        聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        舉例講解Python中的死鎖、可重入鎖和互斥鎖

        舉例講解Python中的死鎖、可重入鎖和互斥鎖:一、死鎖 簡單來說,死鎖是一個資源被多次調(diào)用,而多次調(diào)用方都未能釋放該資源就會造成死鎖,這里結(jié)合例子說明下兩種常見的死鎖情況。 1、迭代死鎖 該情況是一個線程迭代請求同一個資源,直接就會造成死鎖: import threading import time
        推薦度:
        標(biāo)簽: python 死鎖
        • 熱門焦點(diǎn)

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 亚洲综合精品伊人久久| 色九月亚洲综合网| 国产高清在线免费视频| a免费毛片在线播放| 亚洲无成人网77777| 国产精品久久香蕉免费播放| 2022免费国产精品福利在线| 亚洲六月丁香六月婷婷蜜芽| 亚洲?V乱码久久精品蜜桃 | MM131亚洲国产美女久久| 日本免费一区二区三区| 国产亚洲一卡2卡3卡4卡新区| 在线亚洲97se亚洲综合在线| 国内精品免费麻豆网站91麻豆| 免费看又黄又爽又猛的视频软件| 久久久久久久亚洲Av无码| 亚洲成人影院在线观看| 成年人免费的视频| 中国videos性高清免费| 亚洲AV无码男人的天堂| 亚洲色大成网站www永久| 亚洲国产一区二区视频网站| 无码国产精品一区二区免费| 久久精品无码免费不卡| 亚洲成aⅴ人片久青草影院按摩| 亚洲国产成人久久精品动漫| 免费在线观看污网站| 国产成人精品免费视频网页大全 | 最近中文字幕大全中文字幕免费| 男人和女人高潮免费网站 | 无码国产精品一区二区免费3p| 相泽南亚洲一区二区在线播放| 亚洲国产精品免费视频| 激情97综合亚洲色婷婷五| 国产乱人免费视频| 国产日本一线在线观看免费| 无码精品国产一区二区三区免费 | 天天爽亚洲中文字幕| 亚洲国产综合专区电影在线| 国产亚洲?V无码?V男人的天堂| 日本免费v片一二三区|