使用普通multiprocessing.Lock(或threading.Lock),您可以簡化以下代碼:
lock = multiprocessing.Lock()
lock.acquire()
try:
...
finally:
lock.release()
進入:
with lock:
...
但是,當我想將一些引數傳遞給 時,我是否仍然可以使用背景關系管理器lock.acquire(...),例如block=or timeout=?例如,我有這樣的代碼:
lock_success = lock.acquire(block=False)
if not lock_success:
return
try:
...
finally:
lock.release()
我看不到將這個引數傳遞給背景關系管理器的方法(因為它在acquire呼叫中而不是建構式中)。
(想法是,with如果無法獲取鎖,則將跳過 -block。)
類似地,threading.Lock它提供了類似的 API。
uj5u.com熱心網友回復:
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()
uj5u.com熱心網友回復:
我懷疑這是不可能的,因為背景關系管理器是如何在 Python 中設計的。背景關系管理器 (CM) 發生的情況是:
with CM:
...
- CM的
__enter__方法被呼叫 - 里面的塊
with運行 - CM的
__exit__方法被呼叫
因此沒有辦法“跳過” with-block 的內部,所以我想這解釋了Lock類的設計。盡管有一些黑暗的魔法方法(應該避免)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/433902.html
標籤:Python 多线程 多处理 python-多线程
上一篇:RestClient和執行緒鎖定
下一篇:解釋協程的有趣行為
