Python 单线程中的os.makedir争用条件?如何确保在继续之前创建目录

Python 单线程中的os.makedir争用条件?如何确保在继续之前创建目录,python,python-3.x,flask,operating-system,race-condition,Python,Python 3.x,Flask,Operating System,Race Condition,我在flask应用程序中有非常奇怪的os.makedir 我有一个用于上传图像的API端点。应根据条件将每个图像分组到目录中。如果目录不存在,则应创建该目录 最初,我的应用程序中有以下代码: # create needed dir if doesn't exist if not os.path.isdir(os.path.dirname(abs_path)): os.mkdir(os.path.dirname(abs_path)) # create a

我在flask应用程序中有非常奇怪的
os.makedir

我有一个用于上传图像的API端点。应根据条件将每个图像分组到目录中。如果目录不存在,则应创建该目录

最初,我的应用程序中有以下代码:

    # create needed dir if doesn't exist
    if not os.path.isdir(os.path.dirname(abs_path)):
        os.mkdir(os.path.dirname(abs_path))

    # create a file and save it into a needed place
    with open(abs_path, 'wb') as f:
        shutil.copyfileobj(fp, f)
        f.flush()
在90%的情况下,它非常有效。但当请求中有两个文件时,它们应该放在同一个目录中,而目录尚未创建,我得到了以下信息:

flask_1  |   File "/app/storage.py", line 101, in save_file
flask_1  |     os.mkdir(os.path.dirname(abs_path))
flask_1  | FileExistsError: [Errno 17] File exists: '/static/df273d04909e71beb8b63b4d1b1c0a969ee6fc15'
在flask调试模式下,使用1个线程,可以在本地复制,100%成功。这似乎是某种Linux/docker或某种缓存竞争条件

然后我简单地将代码更改为:

if not os.path.isdir(os.path.dirname(abs_path)):
    try:
        os.mkdir(os.path.dirname(abs_path))
    except FileExistsError:
        # Another thread was already created the directory when
        # several simultaneous requests has come
        if os.path.isdir(os.path.dirname(abs_path)):
            pass
        else:
            raise

    # create a file and save it into a needed place
    with open(abs_path, 'wb') as f:
        shutil.copyfileobj(fp, f)
        f.flush()
问题已经解决了

但我担心在生产中使用此代码,因为很奇怪,相同的检查会产生不同的结果

如何确保在继续第一次请求处理之前确实创建了目录

p.S.文件已就位,第二个代码段和两个文件均已就位。第一个文件只包含目录中的第一个文件,第二个文件出错

也就是说,对于第一个代码片段,Flask认为一切正常并继续

接受一个参数
存在_ok
,当该参数为
True
时,如果dir存在,它将不会引发错误

os.makedirs(os.path.dirname(abs_path), exist_ok=True)

是的,我知道这个选择。但我和我的团队负责人主要是想了解内部流程,而不仅仅是处理错误。您确定该流程是在单个线程中运行的吗?