1
noqwerty 2020-06-17 06:45:28 +08:00
建议读一下文档: https://docs.python.org/3/library/threading.html#threading.Lock.acquire
另外也可以从语义上去理解,锁 (Lock) 只有上锁和解锁两种状态,不存在你说的开两次锁的情况。 |
2
cigarzh 2020-06-17 07:03:17 +08:00
你说的那玩意是 threading.RLock()
|
3
js8510 2020-06-17 09:08:59 +08:00
哇。leetcode 都有一千多题了呀。我还真在 在生产环境见过类似的情况。但是实现和你发的这个有不同
作者的意图应该是这样, ··· from threading import Lock class FooBar: def __init__(self, n): self.n = n self.foo_lock = Lock() self.bar_lock = Lock() self.bar_lock.acquire() # <---- 1 def foo(self, printFoo: 'Callable[[], None]') -> None: for i in range(self.n): self.foo_lock.acquire() # <---- 2 | # <---- 5, blocked here and wait for foo_lock # printFoo() outputs "foo". Do not change or remove this line. printFoo() # <---- 3 self.bar_lock.release() # <---- 4 def bar(self, printBar: 'Callable[[], None]') -> None: for i in range(self.n): self.bar_lock.acquire() # <---- 2 and blocked here and wait for bar_lock # printBar() outputs "bar". Do not change or remove this line. printBar() # <---- 5 self.foo_lock.release() # <---- 6 ··· |
4
lpts007 2020-06-17 10:12:38 +08:00
```python
from threading import Lock ``` |
5
gzfrankie 2020-06-17 13:15:32 +08:00
因为那段代码,foo_lock 和 bar_lock 是两个不同的 lock 。
流程: 1. 在__INIT__里锁了 bar_lock 2.这时候两个进程同时开始,bar 锁在 self.bar_lock.acquire()那里不动了 3.foo 正常运行,运行结束了之后 self.bar_lock.release()解锁 bar_lock ;运行到第二次 foo_lock.acquire(),锁住不动 4.bar_lock 被解锁,bar 继续运行,到最后解锁 foo_lock 5.foo_lock 被解锁,foo 继续运行 所以是两个 lock,在 foo 里解 bar_lock,在 bar 里解 foo_lock,不存在同一个 threadacquire 了两次同一个 lock 的情况 |
6
gzfrankie 2020-06-17 13:27:58 +08:00
在看了一下你的疑问,补充一下:
"那么我的问题来了,如果被 acquire 了两次的话,我们需要不要 release 两次? 看代码,我们不需要 release 两次。" 不需要 release 两次,因为 1. 如果第一次 acquire()成功,acquire()返回 True,程序运行 2.第二次 acquire(),由于 lock 并没有被 release,程序被停在 acquire 那行;想让程序继续运行,需要在别的地方把这个 lock release 掉。 3.release 一个已被解锁的 lock,python 会 throw RuntimeError |