我正在尝试解决LeetCode问题,Print Zero Even Odd:
我使用^{
import threading
from typing import Callable, Optional
class ZeroEvenOdd:
def __init__(self, n: int):
self.n = n
self.i = 0
self.last_printed: Optional[int] = None
self.condition = threading.Condition()
def zero(self, printNumber: Callable[[int], None]) -> None:
with self.condition:
self.condition.wait_for(lambda: self.last_printed is None or self.last_printed > 0)
if self.done:
return
printNumber(0)
self.last_printed = 0
self.i += 1
self.condition.notify_all()
def even(self, printNumber: Callable[[int], None]) -> None:
with self.condition:
self.condition.wait_for(lambda: self.last_printed == 0 and self.i % 2 == 0)
if self.done:
return
self._print_and_notify()
def odd(self, printNumber: Callable[[int], None]) -> None:
with self.condition:
self.condition.wait_for(lambda: self.last_printed == 0 and self.i % 2 == 1)
if self.done:
return
self._print_and_notify()
def _print_and_notify(self) -> None:
printNumber(self.i)
self.last_printed = self.i
self.condition.notify_all()
@property
def done(self) -> bool:
if self.last_printed is not None and self.last_printed >= self.n:
self.condition.release()
self.condition.notify_all()
return True
return False
def printNumber(x: int) -> None:
print(x)
zero_even_odd = ZeroEvenOdd(n=5)
threadA = threading.Thread(target=zero_even_odd.zero, args=(printNumber,))
threadB = threading.Thread(target=zero_even_odd.even, args=(printNumber,))
threadC = threading.Thread(target=zero_even_odd.odd, args=(printNumber,))
if __name__ == "__main__":
threadA.start()
threadB.start()
threadC.start()
但是,当我运行这个时,我发现它打印0
,然后1
,然后无限期挂起:
我有点困惑,为什么在第一次调用odd()
之后,zero()
就不再被调用了。毕竟,在打印odd()
中的1
之后,self.last_printed
被设置为1
,这应该触发zero()
方法的wait_for()
条件。在
你知道为什么这个程序不能正常工作吗?在
正如Sraw指出的,我的代码中没有循环,因此没有理由期望再次调用
zero()
。最后,我使用threading.Lock
对象以不同的方式解决了这个问题:这将打印所需的输出:
^{pr2}$并以相当快且节省内存的方式解决LeetCode问题:
相关问题 更多 >
编程相关推荐