多处理时正确检查文件是不是存在
Posted
技术标签:
【中文标题】多处理时正确检查文件是不是存在【英文标题】:correctly checking file existence while multiprocessing多处理时正确检查文件是否存在 【发布时间】:2016-08-06 07:42:35 【问题描述】:我有一个函数myfunc
,它在并行处理中被调用。当我让多个进程共享同一个目标文件夹时,它们都并行调用myfunc
并检查目标文件夹的存在。如果它已经存在,没有问题。但是,如果在启动脚本之前该文件夹不存在,那么第一个进程将进入 if 块并创建该文件夹。另一方面,将有另一个进程会同时进入相同的 if block "almost",会发现该文件夹不存在,并会尝试创建它,而第一个进程实际上正在创建它或已经做到了。所以在某个时候会有一个OSError
告诉文件夹已经存在。
在多处理时有没有一种干净的方法来处理这个问题?在启动我的进程之前,我正在考虑将目标文件夹从功能 myfunc
中处理出来。但是,为了知识,找到使用多处理的解决方案会很好。
import os, sys
def myfunc(file_names, destination=None, file_permission=None, verbose=False):
absPath = os.path.abspath(file_names[0])
baseName = os.path.basename(absPath)
dirName = os.path.dirname(absPath)
destination_folder = "/default/destination" if destination is None \
else os.path.abspath(destination)
if not os.path.isdir(destination_folder):
os.mkdir(destination_folder)
os.chmod(destination_folder, file_permission)
if verbose:
print "Created directory", destination_folder
【问题讨论】:
那么,捕捉到异常了吗? 【参考方案1】:在大多数情况下,检查文件/文件夹是否存在并根据结果采取行动是根本错误的,因为即使您不是多处理,您也不知道计算机上正在运行什么。也很难保证其他人以后不会运行您的流程的多个副本,即使您最初并不打算这样做。
最可靠的方法是始终尝试创建文件夹,并默默地忽略“但已存在”错误。 (不要忽略其他错误,例如“但您没有该权限”!)即使您在开始多处理之前进行了一次检查,这仍然是最好的方法。
【讨论】:
你认为捕获异常和锁应该结合使用吗?我实际上不知道在你的和 th3an0maly 之间哪个答案最合适。 要健壮,您必须捕获异常。在一般情况下,即使您的锁是完美的,另一个程序可能会意外地从您下面更改文件或文件夹。完成此操作后,您可以评估是否也使用锁或条件来增加价值。肯定有它们有用的地方,但我不认为这是其中之一。一旦你捕捉到异常,锁就会给这个解决方案增加额外的复杂性,而不会提供任何额外的安全性。【参考方案2】:使用threading
模块中的Lock
解决并发问题:
import os, sys
from threading import Lock
def myfunc(lock, ...):
... do stuff as usual ...
with lock:
destination_folder = "/default/destination" if destination is None \
else os.path.abspath(destination)
... do everything else as usual ...
if __name__ == "__main__":
my_lock = Lock()
myfunc(my_lock, ...)
【讨论】:
如果使用multiprocessing
(根据标题),则相当于multiprocessing.Lock
。以上是关于多处理时正确检查文件是不是存在的主要内容,如果未能解决你的问题,请参考以下文章
文件存在,如果语句检查,如果文件不存在,则不会返回正确的输出,C#
检查 EJS 模板中是不是存在变量的正确方法是啥(使用 ExpressJS)?