获取多处理.如果没有阻塞或超时,请锁定with语句



使用普通multiprocessing.Lock(或threading.Lock(可以简化以下代码:

lock = multiprocessing.Lock()
lock.acquire()
try:
...
finally:
lock.release()

进入:

with lock:
...

但是,当我想将一些参数传递给lock.acquire(...)(如block=timeout=(时,我还能使用上下文管理器吗?例如,我有这样的代码:

lock_success = lock.acquire(block=False)
if not lock_success:
return
try:
...
finally:
lock.release()

我看不出有什么方法可以将此参数传递给上下文管理器(因为它在acquire调用中,而不是构造函数中(。

(这个想法是,如果无法获取锁,with-块将被跳过。(

类似于提供类似API的threading.Lock

TLDR;您不能使用内置的锁上下文管理器,但它仍然可以相当干净地完成。

它几乎可以工作,因为Lock.__enter__()确实返回了从对acquire()的调用返回的值,该值应该是获取锁的布尔成功或失败。

l = Lock()
with l as success:
if success:
print("run some code")
else:
print("skip the code")

然而,令人沮丧的是,无法将参数传递给acquire的内部调用(此处为硬编码参数(。我建议您编写自己的上下文管理器来解决这个问题,因为它非常简单:

from multiprocessing import Lock
from contextlib import contextmanager
@contextmanager
def get_lock(lock, block=True, timeout=None):
held = lock.acquire(block=block, timeout=timeout)
try:
yield held
finally:
if held:
lock.release()
#### example usage ####
l = Lock()
#lock should be acquired so success == True
with get_lock(l) as success:
if success:
print("run some code")
else:
print("skip the code")
l.acquire()
#lock won't be acquired and block will proceed after timeout
#use the value of success to determine what to do
with get_lock(l, True, 3) as success:
if success:
print("run some code")
else:
print("skip the code")
l.release()

我怀疑这是不可能的,因为上下文管理器是如何在Python中设计的。上下文管理器(CM(的作用是:

with CM:
...
  • CM的__enter__方法被调用
  • with内部的块运行
  • CM的__exit__方法被调用

因此;跳过";with块的内部,所以我想这解释了Lock类的设计。尽管有一些黑暗的魔法方法(应该避免(。

相关内容

  • 没有找到相关文章

最新更新