Python并行执行-threading.Lock无法按预期工作

The*_*CAL 4 python parallel-processing locking

我目前有一个global Lock = threading.Lock(),并进行以下呼叫:

Parallel(n_jobs=2)(delayed(serialRemove)(dir,c,b,l,f) for f in os.listdir(dir))
Run Code Online (Sandbox Code Playgroud)

使用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()
Run Code Online (Sandbox Code Playgroud)

通话的部分结果是:
10.txt开始
11.txt开始
20.txt开始
我不明白如果我将代码放在Lock中,怎么会有两个开始打印。有什么简单的方法可以保护代码块,所以理想情况下我得到:
10.txt开始
10.txt结束
11.txt开始
11.txt结束
20.txt开始
20.txt结束

aba*_*ert 5

threading.Lock 仅在同一进程的线程之间起作用。

在这里,实际上不知道您要使用哪个库进行并行处理,这很难确定,但是几乎可以肯定,它是在单独的进程中执行任务的。(由于存在GIL,因此至少在CPython中,在同一进程中启动线程的任何方法都不会对CPU绑定的代码获得任何有效的并行性。因此,它们都没有这样做。)

因此,如果您尝试使用threading.Lock其他进程中的全局对象,则将在每个进程中获得完全独立的锁。因此,锁定它没有任何好处。(使用一些并行库(在每个平台上可能有所不同),您会得到一个错误信息。但是,它不可能完成您想要的操作。)

大多数并行化库都有自己的锁类型,可以与它们的多处理方式配合使用。如果是这样,请使用您的磁带库随附的那个。

如果没有,则取决于您的库的工作方式,multiprocessing.Lock可以解决问题。

如果没有,您将必须使用例如锁文件(可能与flock/ 一起使用lockf,或依赖Windows独占打开或其他方式)显式实现某些功能。

另外,请注意,多个库中至少有一个具有可以使您的示例代码行[ joblib] 有意义的API ,是专门为没有任何共享的任务而设计的,因此不应与完全锁定。(multiprocessing.Lock无论如何它都可能会起作用,但是您真的不应该指望它。)