多处理时正确检查文件是不是存在

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

以上是关于多处理时正确检查文件是不是存在的主要内容,如果未能解决你的问题,请参考以下文章

检查html元素是不是存在的正确方法[重复]

文件存在,如果语句检查,如果文件不存在,则不会返回正确的输出,C#

SQL命令未正确结束是啥原因,去掉;也不行

检查 EJS 模板中是不是存在变量的正确方法是啥(使用 ExpressJS)?

为啥复制东西到U盘总显示;找不到指定文件 请确定指定的路径及文件名是不是正确 急急急急!!!

VBA验证文本框中是不是存在文本,然后检查日期是不是格式正确