Python3 : 我可以同时锁多把锁吗?

Python3 : can I lock multiple locks simultaneously?

我有多个锁锁住我 API 的不同部分。

要锁定任何方法,我会这样做:

import threading

class DoSomething:
    def __init__():
        self.lock = threading.Lock()

    def run(self):
        with self.lock:
            # do stuff requiring lock here

对于大多数用例,这都很好。

但是,我不确定我在需要多个锁时所做的工作是否有效:

import threading

class DoSomething:
    def __init__():
        self.lock_database = threading.Lock()
        self.lock_logger = threading.Lock()

    def run(self):
        with self.lock_database and self.lock_logger:
            # do stuff requiring lock here

事实上,代码运行得很好,但我不确定它是否按我想要的方式运行。

我的问题是:锁是同时获取的还是第一个获取到第二个才获取到。

我之前的代码是这样的吗?

with self.lock1:
    with self.lock2:
        # do stuff here

事实上,代码目前可以工作,但是,由于我的线程同时需要同一个锁的可能性一开始就非常低,我可能会在以后调试时头疼不已

我问这个问题是因为我非常不确定如何测试我的代码以确保它按预期工作并且同样有兴趣获得答案并知道我如何测试它以确保它工作(而不是最终用户为我测试它)

是的,你可以这样做,但要小心deadlocks。当一个线程无法取得进展时,就会发生死锁,因为它需要获取其他线程持有的锁,但第二个线程无法取得进展,因为它想要第一个线程已经持有的锁。

您的代码示例首先锁定 lock_database,然后锁定 lock_logger。如果您可以保证任何同时锁定它们的线程将始终以相同的顺序锁定它们,那么您就安全了。这样永远不会发生死锁。但是,如果一个线程在尝试锁定 lock_logger 之前锁定了 lock_database,而另一个线程试图以相反的顺序同时获取它们,那就是等待发生的死锁。

看起来很简单。它是,除了...

...在一个更复杂的程序中,锁附加到传递给不同函数的对象,那么它可能并不那么容易,因为一个线程可能调用一些 foobar(a, b) 函数,而另一个线程在相同的两个对象上调用相同的 foobar(),除了对象被切换。