我目前有一个全局Lock = threading.Lock()
,并进行以下调用:
Parallel(n_jobs=2)(delayed(serialRemove)(dir,c,b,l,f) for f in os.listdir(dir))
使用jobLib。在serialRemove
,我有
Lock.acquire()
print(f+' begin')
if h in hashes:
try:
os.remove(path)
if l: print('Removing ' + path)
removed += 1
except os.error:
print('Encountered error removing file')
else:
hashes.add(h)
print(f+' end')
Lock.release()
部分通话结果如下:
10.txt开始
11.txt开始
20.txt开始
如果我将代码包含在Lock中,我不明白如何有两个开始打印。是否有任何简单的方法来保护代码块,理想情况下我得到:
10.txt开始
10.txt结束
11.txt开始
11.txt结束
20.txt开始
20.txt结束
答案 0 :(得分:4)
threading.Lock
仅适用于同一进程的线程。
如果没有真正知道你在这里用于并行化的库,那么很难确定,但它几乎肯定会在不同的进程中执行任务。 (在同一进程中启动线程的任何东西,至少在CPython中,由于GIL,不会为CPU绑定代码获得任何有效的并行性。因此,他们都没有这样做。)
因此,如果您尝试使用来自其他进程的全局threading.Lock
对象,那么您将在每个进程中获得完全独立的锁定。因此,锁定它没有任何好处。 (对于某些并行库 - 每个平台可能不同 - 你会得到一个错误。但是它没有办法可能做你想要的。)
大多数并行化库都有自己的锁类型,可以使用它们的多处理风格。如果是的话,请使用您的图书馆附带的那个。
如果没有,根据您的图书馆的工作方式,multiprocessing.Lock
可能会有所帮助。
如果没有,您将必须使用例如锁定文件(可能与flock
/ lockf
一起,或依赖Windows独占打开,或其他)明确实现某些内容。
另外,请注意,具有可以理解您的示例代码行[{joblib
]的API的多个库中的至少一个是明确设计用于没有任何共享的任务,并且因此根本不应该使用锁。 (无论如何,它可能会与multiprocessing.Lock
一起使用,但你真的不应该依赖它。)