正确锁定方法调用

时间:2012-11-23 15:57:06

标签: python concurrency thread-safety

我在和一个测量设备说话。我基本上发送命令并接收答案。但是我提供了一个方法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

2 个答案:

答案 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 __()方法中。