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

您的位置:首頁技術文章
文章詳情頁

Python 防止死鎖的方法

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

問題

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

解決方案

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

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):]

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

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()

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

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()

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

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>>>

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

討論

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

死鎖的檢測與恢復是一個幾乎沒有優雅的解決方案的擴展話題。一個比較常用的死鎖檢測與恢復的方案是引入看門狗計數器。當線程正常 運行的時候會每隔一段時間重置計數器,在沒有發生死鎖的情況下,一切都正常進行。一旦發生死鎖,由于無法重置計數器導致定時器 超時,這時程序會通過重啟自身恢復到正常狀態。

避免死鎖是另外一種解決死鎖問題的方式,在進程獲取鎖的時候會嚴格按照對象id升序排列獲取,經過數學證明,這樣保證程序不會進入 死鎖狀態。證明就留給讀者作為練習了。避免死鎖的主要思想是,單純地按照對象id遞增的順序加鎖不會產生循環依賴,而循環依賴是 死鎖的一個必要條件,從而避免程序進入死鎖狀態。

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

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() 函數。如果代碼中的某部分繞過acquire 函數直接申請鎖,那么整個死鎖避免機制就不起作用了。

以上就是Python 防止死鎖的方法的詳細內容,更多關于Python 防止死鎖的資料請關注好吧啦網其它相關文章!

標簽: Python 編程
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
午夜精品福利影院| 国产精品毛片久久| japanese国产精品| 亚洲一区二区动漫| 亚洲最新无码中文字幕久久| 免费国产自久久久久三四区久久| av日韩中文| 亚洲另类黄色| 国产一区二区三区四区| 欧美特黄a级高清免费大片a级| 91亚洲国产| 成人午夜网址| 91偷拍一区二区三区精品| 色黄视频在线观看| 激情黄产视频在线免费观看| av中文字幕在线观看第一页| 欧美羞羞视频| 美女网站一区| 亚洲在线国产日韩欧美| 亚洲一区日本| 日韩国产欧美视频| 国语精品一区| 久久精品影视| 六月婷婷一区| 亚洲精品自拍| 国产激情久久| 精品少妇av| 久久91导航| 欧美特黄一区| 奇米狠狠一区二区三区| 久久久精品国产**网站| 福利在线一区| 午夜视频精品| 日本亚洲视频| 久久一区精品| 国产精品久久久久久久久久10秀| av高清不卡| 美女国产一区| 国产欧美三级| 国产aⅴ精品一区二区四区| 免费在线小视频| 在线视频精品| 国产美女久久| 四虎影视精品| 天堂俺去俺来也www久久婷婷| 国产日韩一区二区三区在线| 中文一区一区三区免费在线观| 日韩精品久久理论片| 丝袜诱惑制服诱惑色一区在线观看 | 国产成人精品亚洲线观看| 亚洲激精日韩激精欧美精品| 卡一卡二国产精品| 久久国产直播| 亚洲精品婷婷| 久久久久久一区二区| 午夜久久美女| 欧美成人aaa| 亚洲激情五月| 老司机免费视频一区二区三区| 婷婷亚洲综合| 国产亚洲久久| 亚洲黄色在线| 精品国产亚洲一区二区三区大结局| 四虎4545www国产精品| 亚洲日本免费电影| 日韩精品亚洲专区| 国产 日韩 欧美一区| 日韩精品免费视频一区二区三区| 欧美韩一区二区| 国产视频久久| 精品亚洲精品| 伊人久久一区| 色天使综合视频| 国产欧美日韩亚洲一区二区三区| 99精品美女| 国产精品资源| 欧美一区=区| 日韩欧美精品一区| 图片区亚洲欧美小说区| 日本大胆欧美人术艺术动态| 在线午夜精品| 日韩一级网站| 婷婷综合社区| 日韩高清一区| 欧美色图国产精品| 欧美亚洲综合视频| 亚洲精品91| 久久精品免费看| 国产91精品对白在线播放| 国产成人a视频高清在线观看| 亚洲青青久久| 免费高潮视频95在线观看网站| 亚洲不卡系列| 视频一区日韩精品| 国产精品久久久久久久久久齐齐| 亚洲最新av| 亚洲精品伊人| 亚洲精品女人| 日韩一区三区| 欧美精品国产白浆久久久久| 日韩av午夜在线观看| 日本一二区不卡| 国产中文在线播放| 91亚洲精品在看在线观看高清| 国产综合色区在线观看| 激情欧美一区| 国产亚洲一区二区三区啪| 精品一区电影| 亚洲图片久久| 国产乱人伦精品一区| 亚洲美洲欧洲综合国产一区| 国产一区三区在线播放| 中文字幕亚洲精品乱码| 亚洲综合三区| 首页国产精品| 福利一区在线| 视频在线在亚洲| 欧美成人基地 | 日韩免费视频| 久久精品亚洲| 欧美亚洲一级| 深夜福利一区| 亚洲色图网站| 亚洲综合激情在线| 蜜桃一区二区三区在线| 日韩中文欧美在线| 日韩在线一二三区| 亚洲字幕久久| 日韩欧美2区| 日韩精品1区2区3区| 免费日韩av| 综合国产精品| 日韩精品免费观看视频| 欧美日韩a区| 国产精品黄色片| 国产精品日韩精品中文字幕| 清纯唯美亚洲综合一区| 日韩精品国产欧美| 国产麻豆一区二区三区| 国产精品美女在线观看直播| 国产欧美欧美| 老色鬼精品视频在线观看播放| 高清久久一区| 国产精品88久久久久久| 六月天综合网| 91福利精品在线观看| 国产精品4hu.www| 精品不卡一区| 久久国产电影| 亚洲精品乱码久久久久久蜜桃麻豆| 免费美女久久99| 日韩成人午夜精品| 国产精品1区| 国产欧美一区二区三区精品酒店| 亚洲精品国产嫩草在线观看| 久久uomeier| 日韩亚洲精品在线| 日韩国产欧美三级| 国产精品久久久久久久久久10秀| 久久在线免费| 久久午夜影视| 欧美一区二区三区久久精品| 精品国产aⅴ| 欧美亚洲国产激情| 亚洲毛片视频| 国产精品视频一区二区三区四蜜臂| 精品一区av| 国产亚洲一区在线| 国产调教精品| 久久久久.com| 亚洲精品一二三**| 精品一区二区三区视频在线播放| 亚洲第一区色| 日韩超碰人人爽人人做人人添| 麻豆国产91在线播放| 午夜欧美精品| 欧美国产亚洲精品| 欧美日韩一区二区三区视频播放| 中文字幕一区二区精品区| 麻豆中文一区二区| 亚洲成人三区| 国产精品视频一区二区三区四蜜臂 | 国产videos久久| 自拍日韩欧美| 欧美亚洲一级| 天堂网在线观看国产精品| 欧美日本一区| 国产一区亚洲| 国产精品色在线网站| 久久天堂成人| 18国产精品| 在线国产一区二区| 你懂的亚洲视频| 国产亚洲在线| 首页国产精品| 日韩av二区在线播放| 久久三级视频| 牛牛精品成人免费视频| 蜜臀久久99精品久久久久宅男 | 亚洲人成精品久久久|