将线程同步责任转移到共享资源中

时间:2014-08-09 15:56:45

标签: python multithreading thread-safety locking

给定一个由多个线程使用的对象(= instance),以下方法是最常见的(据我所知):

共享资源:

class Resource():
    def return_some_value(self):
      return self.somevalue

全局(或父上下文):

lock = Lock()
res = Resource()

在访问线程中:

lock.acquire()
res.return_some_value()
lock.release()

显然,访问线程负责锁定和解锁共享资源。

让我们假定共享资源更复杂,一些方法/属性是只读的,而其他方法/属性则不是。现在使用资源的线程必须知道哪个是哪个并相应地锁定。这显然容易出错,我有时无法选择放置Lock对象的位置。

现在我的问题:是否有可能将责任转移到正确锁定到共享资源本身?它甚至有意义吗? 类似的东西:

class Resource():
    def __init__(self):
        self.lock = Lock()
    def return_some_value(self):
        self.lock.acquire()
        return self.somevalue
        self.lock.release() # obviously this won't work

1 个答案:

答案 0 :(得分:2)

是的,这样做非常有意义。您也可以use a Lock as a context manager确保它始终发布:

class Resource():
    def __init__(self):
        self.lock = Lock()

    def return_some_value(self):
        with self.lock:  # Lock gets acquired
            return self.somevalue  # Lock gets released

Lock的所有者基于获取它的主题。许多不同的调用者可以从不同的线程调用您的Resource对象,并且锁定将表现得恰当。

如果您需要在Resource上调用多个方法,这些方法要求您在整个时间段内挂起锁定,这将无法正常工作。在这种情况下,您可能需要考虑使资源本身可锁定:

class Resource():
    def __init__(self):
        self.lock = Lock()

    def __enter__(self):
        self.lock.acquire()

    def __exit__(self, *args, **kwargs):
        self.lock.release()

    def return_some_value(self):
        return self.somevalue

    def some_method(self):
        # stuff

    def some_other_method(self):
        # stuff

r = Resource()
with r:
    r.some_method()
    r.some_other_method()
    val = r.return_some_value()