2012-11-23 47 views
2

我正在与测量设备通话。我基本上发送命令并接收答案。但我提供了一个方法ask发送一个命令并回读答案。如果我锁定了这个方法,由于被调用的方法readwrite锁定,我也会发生死锁。如果我不锁定另一个线程,可以在我阅读之前窃取答案或写信。你将如何实现这一点?正确锁定方法调用

import threading 

class Device(object): 
    lock = threading.Lock() 
    def ask(self, value): 
     # can't use lock here would block 
     self.write(value) # another thread could start reading the answer 
     return self.read() 

    def read(self): 
     with self.lock: 
      # read values from device 

    def write(self, value): 
     with self.lock: 
      # send command to device 
+0

恭喜,您刚刚发现STM支持者在说“锁不合作”时谈论的一件事。 – delnan

+3

不应该是'lock = threading.Lock()'括号吗? –

+0

@StevenRumbalski Ups,我的坏。修复 :) – P3trus

回答

3

使用threading.RLock()避免单一线程内争用:

一个可重入锁是原始的同步可以由同一个线程来获取 多次。在内部,除了原始锁使用的锁定/解锁状态外,它还使用 “拥有线程”和“递归级别”的概念。在锁定状态下, 某些线程拥有锁定;在解锁状态下,没有线程拥有它。

1

您可以使用threading.RLock()对象来执行可重入锁定。但是这样更好地重写代码,它不需要RLock。例如,你可以删除写(锁),read()和改写问()类似的方式在旧版本的Python工作慢

with self.lock: 
     self.write(value) 
     r = self.read() 
    return r 

RLOCK(),因为它是在执行更复杂。

另请注意,在您编写的代码中,您将为所有实例获取一个锁。在某些情况下,它是合适的(例如,如果你只有一个设备和许多实例),但总的来说不是。如果你想为不同的实例使用不同的锁,请将其初始化放在__init __()方法中。

相关问题