日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

Python 防止死鎖的方法

瀏覽:30日期:2022-07-15 18:55:22

問題

你正在寫一個多線程程序,其中線程需要一次獲取多個鎖,此時如何避免死鎖問題。

解決方案

在多線程程序中,死鎖問題很大一部分是由于線程同時獲取多個鎖造成的。舉個例子:一個線程獲取了第一個鎖,然后在獲取第二個鎖的 時候發(fā)生阻塞,那么這個線程就可能阻塞其他線程的執(zhí)行,從而導(dǎo)致整個程序假死。 解決死鎖問題的一種方案是為程序中的每一個鎖分配一個唯一的id,然后只允許按照升序規(guī)則來使用多個鎖,這個規(guī)則使用上下文管理器 是非常容易實現(xiàn)的,示例如下:

import threadingfrom contextlib import contextmanager# Thread-local state to stored information on locks already acquired_local = threading.local()@contextmanagerdef acquire(*locks): # Sort locks by object identifier locks = sorted(locks, key=lambda x: id(x)) # Make sure lock order of previously acquired locks is not violated acquired = getattr(_local,’acquired’,[]) if acquired and max(id(lock) for lock in acquired) >= id(locks[0]): raise RuntimeError(’Lock Order Violation’) # Acquire all of the locks acquired.extend(locks) _local.acquired = acquired try: for lock in locks: lock.acquire() yield finally: # Release locks in reverse order of acquisition for lock in reversed(locks): lock.release() del acquired[-len(locks):]

如何使用這個上下文管理器呢?你可以按照正常途徑創(chuàng)建一個鎖對象,但不論是單個鎖還是多個鎖中都使用 acquire() 函數(shù)來申請鎖, 示例如下:

import threadingx_lock = threading.Lock()y_lock = threading.Lock()def thread_1(): while True: with acquire(x_lock, y_lock): print(’Thread-1’)def thread_2(): while True: with acquire(y_lock, x_lock): print(’Thread-2’)t1 = threading.Thread(target=thread_1)t1.daemon = Truet1.start()t2 = threading.Thread(target=thread_2)t2.daemon = Truet2.start()

如果你執(zhí)行這段代碼,你會發(fā)現(xiàn)它即使在不同的函數(shù)中以不同的順序獲取鎖也沒有發(fā)生死鎖。 其關(guān)鍵在于,在第一段代碼中,我們對這些鎖進(jìn)行了排序。通過排序,使得不管用戶以什么樣的順序來請求鎖,這些鎖都會按照固定的順序被獲取。 如果有多個 acquire() 操作被嵌套調(diào)用,可以通過線程本地存儲(TLS)來檢測潛在的死鎖問題。 假設(shè)你的代碼是這樣寫的:

import threadingx_lock = threading.Lock()y_lock = threading.Lock()def thread_1(): while True: with acquire(x_lock): with acquire(y_lock):print(’Thread-1’)def thread_2(): while True: with acquire(y_lock): with acquire(x_lock):print(’Thread-2’)t1 = threading.Thread(target=thread_1)t1.daemon = Truet1.start()t2 = threading.Thread(target=thread_2)t2.daemon = Truet2.start()

如果你運行這個版本的代碼,必定會有一個線程發(fā)生崩潰,異常信息可能像這樣:

Exception in thread Thread-1:Traceback (most recent call last): File '/usr/local/lib/python3.3/threading.py', line 639, in _bootstrap_inner self.run() File '/usr/local/lib/python3.3/threading.py', line 596, in run self._target(*self._args, **self._kwargs) File 'deadlock.py', line 49, in thread_1 with acquire(y_lock): File '/usr/local/lib/python3.3/contextlib.py', line 48, in __enter__ return next(self.gen) File 'deadlock.py', line 15, in acquire raise RuntimeError('Lock Order Violation')RuntimeError: Lock Order Violation>>>

發(fā)生崩潰的原因在于,每個線程都記錄著自己已經(jīng)獲取到的鎖。 acquire() 函數(shù)會檢查之前已經(jīng)獲取的鎖列表, 由于鎖是按照升序排列獲取的,所以函數(shù)會認(rèn)為之前已獲取的鎖的id必定小于新申請到的鎖,這時就會觸發(fā)異常。

討論

死鎖是每一個多線程程序都會面臨的一個問題(就像它是每一本操作系統(tǒng)課本的共同話題一樣)。根據(jù)經(jīng)驗來講,盡可能保證每一個 線程只能同時保持一個鎖,這樣程序就不會被死鎖問題所困擾。一旦有線程同時申請多個鎖,一切就不可預(yù)料了。

死鎖的檢測與恢復(fù)是一個幾乎沒有優(yōu)雅的解決方案的擴(kuò)展話題。一個比較常用的死鎖檢測與恢復(fù)的方案是引入看門狗計數(shù)器。當(dāng)線程正常 運行的時候會每隔一段時間重置計數(shù)器,在沒有發(fā)生死鎖的情況下,一切都正常進(jìn)行。一旦發(fā)生死鎖,由于無法重置計數(shù)器導(dǎo)致定時器 超時,這時程序會通過重啟自身恢復(fù)到正常狀態(tài)。

避免死鎖是另外一種解決死鎖問題的方式,在進(jìn)程獲取鎖的時候會嚴(yán)格按照對象id升序排列獲取,經(jīng)過數(shù)學(xué)證明,這樣保證程序不會進(jìn)入 死鎖狀態(tài)。證明就留給讀者作為練習(xí)了。避免死鎖的主要思想是,單純地按照對象id遞增的順序加鎖不會產(chǎn)生循環(huán)依賴,而循環(huán)依賴是 死鎖的一個必要條件,從而避免程序進(jìn)入死鎖狀態(tài)。

下面以一個關(guān)于線程死鎖的經(jīng)典問題:“哲學(xué)家就餐問題”,作為本節(jié)最后一個例子。題目是這樣的:五位哲學(xué)家圍坐在一張桌子前,每個人 面前有一碗飯和一只筷子。在這里每個哲學(xué)家可以看做是一個獨立的線程,而每只筷子可以看做是一個鎖。每個哲學(xué)家可以處在靜坐、 思考、吃飯三種狀態(tài)中的一個。需要注意的是,每個哲學(xué)家吃飯是需要兩只筷子的,這樣問題就來了:如果每個哲學(xué)家都拿起自己左邊的筷子, 那么他們五個都只能拿著一只筷子坐在那兒,直到餓死。此時他們就進(jìn)入了死鎖狀態(tài)。 下面是一個簡單的使用死鎖避免機制解決“哲學(xué)家就餐問題”的實現(xiàn):

import threading# The philosopher threaddef philosopher(left, right): while True: with acquire(left,right): print(threading.currentThread(), ’eating’)# The chopsticks (represented by locks)NSTICKS = 5chopsticks = [threading.Lock() for n in range(NSTICKS)]# Create all of the philosophersfor n in range(NSTICKS): t = threading.Thread(target=philosopher, args=(chopsticks[n],chopsticks[(n+1) % NSTICKS])) t.start()

最后,要特別注意到,為了避免死鎖,所有的加鎖操作必須使用 acquire() 函數(shù)。如果代碼中的某部分繞過acquire 函數(shù)直接申請鎖,那么整個死鎖避免機制就不起作用了。

以上就是Python 防止死鎖的方法的詳細(xì)內(nèi)容,更多關(guān)于Python 防止死鎖的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Python 編程
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
91精品一区二区三区综合在线爱| 亚洲精品日韩久久| 国产精品一级| 日韩国产一区二| 国产精品多人| 桃色av一区二区| 日韩视频中文| 日韩福利视频一区| 麻豆91精品视频| av一区在线| 视频在线观看一区二区三区| 亚洲天堂av资源在线观看| 国产午夜久久av| 亚洲电影有码| 日韩中文av| 精品国产成人| 六月天综合网| 成人高清一区| 午夜亚洲福利| 一本大道色婷婷在线| 视频一区中文字幕精品| 久久国产影院| 国产精品免费精品自在线观看| 成人在线观看免费视频| 日韩精品一区二区三区中文| 中文字幕在线免费观看视频| 亚洲专区视频| 成人羞羞在线观看网站| 日韩高清一区| 亚洲少妇在线| 久久久久99| 精品国产亚洲日本| 日本午夜精品久久久久| 精品一区在线| 国产一区二区视频在线看| 亚洲乱码一区| 99国产精品| 欧美精品日日操| 成人午夜亚洲| 中文视频一区| 国产一区二区三区探花| 国产精品.xx视频.xxtv| 国产在线欧美| 综合国产视频| 国产亚洲精品美女久久久久久久久久| 国产精品久久久久久av公交车| 欧美日韩a区| 久久精品福利| 国产精品一线| 另类小说一区二区三区| 日韩精品一区二区三区免费视频 | 久久视频精品| 日韩精品永久网址| 97精品国产| 亚洲精品成a人ⅴ香蕉片| 欧美日韩日本国产亚洲在线| 黄色亚洲精品| 亚洲久久视频| 国产精品久久久久久av公交车| 国产精品一区二区精品视频观看 | 精品久久影院| 精品一区二区三区亚洲| 丰满少妇一区| 久久国产日韩| 丝袜美腿成人在线| 亚洲精品影院在线观看| 国产亚洲精aa在线看| 国产成人免费| 99精品国产一区二区三区| 亚洲在线一区| 国产欧美日韩影院| 精品久久网站| av资源亚洲| 国产美女精品| 欧美精品中文| 91欧美在线| 国产美女一区| 精品视频91| 热久久国产精品| 久久久久伊人| 国产一区白浆| 国产精品多人| 亚洲免费成人| 久久亚洲精品中文字幕| 亚洲一级影院| 青青草精品视频| 国产 日韩 欧美 综合 一区 | 精品久久影院| 免费精品视频| 日韩综合小视频| 四虎884aa成人精品最新| 日本午夜免费一区二区| 国产精品高颜值在线观看| 一区二区三区国产在线| 色88888久久久久久影院| 国产视频网站一区二区三区| 亚州av乱码久久精品蜜桃| 麻豆精品在线| 亚洲乱码视频| 精品国产乱码| 亚洲欧美日韩国产| 免费在线观看视频一区| 国产精品一二| 亚洲久久在线| 在线一区视频观看| 99久久夜色精品国产亚洲1000部| 亚洲精品91| 亚洲黄色影院| 激情久久99| 午夜精品影视国产一区在线麻豆| 午夜精品成人av| 国产精品第一| 日韩高清一区在线 | 久久麻豆视频| 欧美成人精品午夜一区二区| 亚洲欧美日韩国产| 久久一区二区三区喷水| 粉嫩av一区二区三区四区五区 | 免费在线观看成人| 亚洲成人va| 日韩欧美视频专区| 福利一区视频| 久久女人天堂| 国产精品夜夜夜| 欧美日韩一区二区国产| 亚洲精品美女91| 亚洲精品在线a| 日本一区二区三区中文字幕| 日韩在线播放一区二区| 视频一区中文| 久久av在线| 日韩精品一二区| 丝袜美腿亚洲色图| 亚洲精品高潮| 国产日韩欧美三级| 久久av网站| 精品久久影院| 成人啊v在线| 欧美国产91| 在线免费观看亚洲| 日韩成人在线看| 欧美亚洲自偷自偷| 国产一区二区三区精品在线观看| 国产v日韩v欧美v| 不卡在线一区| 伊人久久大香伊蕉在人线观看热v| 久久国产精品久久w女人spa| 日韩av中文字幕一区二区| 国产精品久久亚洲不卡| 成人免费电影网址| 中文字幕一区二区三区四区久久| 97成人超碰| 欧美天堂视频| 在线精品福利| 日韩久久电影| 日本中文字幕一区二区视频| 国产66精品| 亚州av日韩av| 国产精品久久久久蜜臀| 99在线精品免费视频九九视| 亚洲不卡视频| 亚洲成人不卡| 国产精品久久亚洲不卡| 一区三区视频| 国产一区丝袜| 911亚洲精品| 国产精品嫩草99av在线| 国产专区精品| 久久激情综合网| 午夜亚洲福利在线老司机| 精品99在线| 欧美日韩一区二区三区不卡视频| 欧美va天堂在线| 国产一区二区三区亚洲| 欧美专区一区二区三区| 欧美二三四区| 精品国产午夜肉伦伦影院| 影音先锋久久精品| 99在线精品视频在线观看| а√天堂8资源中文在线| 日本麻豆一区二区三区视频| 一区二区三区四区日韩| 另类国产ts人妖高潮视频| 欧美亚洲国产一区| 蜜桃精品在线| 日韩一区二区中文| 精品女同一区二区三区在线观看| 中文字幕在线高清| 国内精品麻豆美女在线播放视频| 青青草国产成人99久久| 日本亚洲最大的色成网站www | 美女视频黄 久久| 久久狠狠久久| 国产精品一区高清| 久久国产精品色av免费看| 欧美一级网址| 麻豆视频观看网址久久| 精品国产乱码久久久久久樱花| 国产一区二区三区探花| 成人在线免费观看网站|