我在和一个测量设备说话。我基本上发送命令并接收答案。但是我提供了一个方法ask
,它发送命令并回读答案。如果我锁定此方法,由于被调用的方法read
和write
锁定,我也会遇到死锁。如果我没有锁定另一个线程可能会在我阅读之前窃取答案或写入。你会如何实现这个?
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 :(得分:3)
使用threading.RLock()
来避免单个线程内的争用:
可重入锁定是可以获取的同步原语 多次由同一个线程。在内部,它使用的概念 “拥有线程”和“递归级别”除了 原始锁使用的锁定/解锁状态。在锁定状态下, 一些线程拥有锁;在解锁状态下,没有线程拥有它。
答案 1 :(得分:1)
您可以使用threading.RLock()对象进行重入锁定。但是以这种方式重写代码更好,它不需要RLock。例如,您可以从write(),read()和重写ask()类似的方式删除锁
with self.lock: self.write(value) r = self.read() return r
旧版本的python中的RLock()运行速度较慢,因为它在实现中更复杂。
另请注意,在您编写的代码中,您将获得一个锁定所有实例。在某些情况下它是合适的(例如,如果您只有一个设备和许多实例),但通常不是。如果您想为不同的实例使用不同的锁,请将其初始化放在__init __()方法中。