Python3:我可以同时锁定多个锁吗?

Mat*_*tte 5 multithreading locking python-3.x

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

要锁定任何方法,我会执行以下操作:

import threading

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

    def run(self):
        with self.lock:
            # do stuff requiring lock here
Run Code Online (Sandbox Code Playgroud)

对于大多数用例来说,这都可以正常工作。

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

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
Run Code Online (Sandbox Code Playgroud)

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

我的问题是:锁是同时获取的还是先获取第一个锁,然后才获取第二个锁。

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

with self.lock1:
    with self.lock2:
        # do stuff here
Run Code Online (Sandbox Code Playgroud)

事实上,代码目前可以工作,但是,由于我的线程同时需要相同锁的可能性非常低,因此我最终可能会在以后的调试中遇到很大的麻烦

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

Sol*_*low 6

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

您的代码示例lock_database首先锁定,然后lock_logger锁定。如果您可以保证锁定它们的任何线程将始终以相同的顺序锁定它们,那么您就是安全的。那样的话绝不会发生僵局。但是,如果一个线程lock_database在尝试锁定之前锁定lock_logger,而其他一些线程尝试以相反的顺序获取它们,那么就会发生死锁。

看起来很容易。确实如此,除了...

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