2016-09-22 152 views
0

我正在使用pyserial通過多處理獲取數據。我分享數據的方式非常簡單。所以:Python:多處理中單鎖的死鎖

我有成員對象在我的課:

self.mpManager = mp.Manager() 
self.shared_return_list = self.mpManager.list() 
self.shared_result_lock = mp.Lock() 

我打電話給我的多過程是這樣的:

process = mp.Process(target=do_my_stuff, 
args=(self.shared_stopped, self.shared_return_list, self.shared_result_lock) 
) 

其中do_my_stuff是一個全球性的功能。

現在部分的填補了處理功能列表:

if len(acqBuffer) > acquisitionSpecs["LengthToPass"]: 
    shared_lock.acquire() 
    shared_return_list.extend(acqBuffer) 
    del acqBuffer[:] 
    shared_lock.release() 

而這需要的是到本地線程使用的是部分:

while len(self.acqBuffer) <= 0 and (not self.stopped): 
    #copy list from shared buffer and empty it 
    self.shared_result_lock.acquire() 
    self.acqBuffer.extend(self.shared_return_list) 
    del self.shared_return_list[:] 
    self.shared_result_lock.release() 

問題

雖然只有1個鎖,但我的程序偶爾會以某種方式在死鎖中結束!等待一段時間後,我的程序凍結了。在鎖之前和之後添加了打印之後,我發現它在鎖上凍結並以某種方式達到死鎖。

如果我使用遞歸鎖,RLock(),它沒有問題。不知道我是否應該那樣做。

這怎麼可能?難道我做錯了什麼?我期望如果兩個進程都試圖獲得鎖,那麼他們應該阻塞,直到另一個進程解鎖鎖。

+0

你有'shared_lock.acquire()'和'self.shared_result_lock.acquire()'。 「shared_lock」變量是什麼不清楚? – Gerrat

+0

@Gerrat這是與參數相同的鎖。 –

回答

0

原來它不是一個死鎖。我的錯!問題是,從設備獲取的數據有時是如此巨大,通過

shared_return_list.extend(acqBuffer) 
del acqBuffer[:] 

複製數據注意到,該方案凍結了很長時間。我通過以塊方式移動數據並限制從設備拉出的數據量來解決此問題。

1

沒有SSCCE,很難知道您的代碼中是否還有其他內容正在執行。

一種可能性是獲取鎖之後拋出異常。嘗試在try/finally子句中包裝每個鎖定的部分。例如。

try: 
    shared_lock.acquire() 
    shared_return_list.extend(acqBuffer) 
    del acqBuffer[:] 
finally: 
    shared_lock.release() 

和:

try: 
    self.shared_result_lock.acquire() 
    self.acqBuffer.extend(self.shared_return_list) 
    del self.shared_return_list[:] 
finally: 
    self.shared_result_lock.release() 

你甚至可以添加例外條款,並記錄引發任何異常,如果這原來是這個問題。

+0

+1教我的東西我不知道,這是如何實現一個「lock_guard」與'終於'。謝謝!但它沒有解決問題。 –

+0

@TheQuantumPhysicist:太糟糕了。我真的認爲這將是問題。如果你能夠創建一個其他人可以運行的小例子,這可能會讓你發現問題,或者幫助其他人更好地幫助你。 – Gerrat

+0

其實我的SSCCE沒有問題。所以我仍在調查是什麼原因造成的。謝謝 :) –