国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

腳本之家,腳本語(yǔ)言編程技術(shù)及教程分享平臺(tái)!
分類導(dǎo)航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務(wù)器之家 - 腳本之家 - Python - Python 防止死鎖的方法

Python 防止死鎖的方法

2020-07-29 23:59D Python

這篇文章主要介紹了Python 防止死鎖的方法,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下

問(wèn)題

你正在寫一個(gè)多線程程序,其中線程需要一次獲取多個(gè)鎖,此時(shí)如何避免死鎖問(wèn)題。

解決方案

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import threading
from contextlib import contextmanager
 
# Thread-local state to stored information on locks already acquired
_local = threading.local()
 
@contextmanager
def 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):]

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import threading
x_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 = True
t1.start()
 
t2 = threading.Thread(target=thread_2)
t2.daemon = True
t2.start()

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import threading
x_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 = True
t1.start()
 
t2 = threading.Thread(target=thread_2)
t2.daemon = True
t2.start()

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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ā)生崩潰的原因在于,每個(gè)線程都記錄著自己已經(jīng)獲取到的鎖。 acquire() 函數(shù)會(huì)檢查之前已經(jīng)獲取的鎖列表, 由于鎖是按照升序排列獲取的,所以函數(shù)會(huì)認(rèn)為之前已獲取的鎖的id必定小于新申請(qǐng)到的鎖,這時(shí)就會(huì)觸發(fā)異常。

討論

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

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

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import threading
 
# The philosopher thread
def philosopher(left, right):
  while True:
    with acquire(left,right):
       print(threading.currentThread(), 'eating')
 
# The chopsticks (represented by locks)
NSTICKS = 5
chopsticks = [threading.Lock() for n in range(NSTICKS)]
 
# Create all of the philosophers
for n in range(NSTICKS):
  t = threading.Thread(target=philosopher,
             args=(chopsticks[n],chopsticks[(n+1) % NSTICKS]))
  t.start()

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

以上就是Python 防止死鎖的方法的詳細(xì)內(nèi)容,更多關(guān)于Python 防止死鎖的資料請(qǐng)關(guān)注服務(wù)器之家其它相關(guān)文章!

原文鏈接:https://python3-cookbook.readthedocs.io/zh_CN/latest/c12/p05_locking_with_deadlock_avoidance.html

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 黄色片视频免费 | 九九香蕉视频 | 日韩高清在线 | 亚洲精品无 | 精品久久久久久久久久久久久久 | 精久久久 | 伊人伊人 | 七七婷婷婷婷精品国产 | 高清一区二区三区视频 | 精品影院 | 国产成人精品一区二区 | 久久99精品久久久久久国产越南 | 大片免费播放在线观看视频 | 欧美亚洲国产一区二区三区 | 久久久www成人免费无遮挡大片 | 精品成人免费一区二区在线播放 | 亚洲精品高潮呻吟久久av | 久久艹天天艹 | 91高清在线 | 精品三级三级三级三级三级 | 亚洲国产高清在线 | 欧美一区免费 | 久久亚洲国产 | 久久国产精品久久国产精品 | 精品成人在线视频 | 成人激情免费视频 | 日韩精品www | 亚洲精品福利 | 97久久精品午夜一区二区 | 欧美精品不卡 | 亚洲午夜精品视频 | 99国产精品久久久久久久成人热 | 综合二区 | 日本中文字幕在线免费观看 | 3344视频| 91免费视频网站 | 观看av | 久久99精品国产.久久久久 | 中文字幕观看 | 午夜精品视频 | 黄a在线|