2016-09-22 208 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没有问题。所以我仍在调查是什么原因造成的。谢谢 :) –