gpt4 book ai didi

python - 单线程中的 os.mkdir 竞争条件?如何确保在继续之前创建目录

转载 作者:太空宇宙 更新时间:2023-11-03 19:54:36 24 4
gpt4 key购买 nike

我在 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'

它可以在具有 1 个线程的 Flask Debug模式下以 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()

问题就解决了。

但我对在生产中使用此代码感到担忧,因为相同的检查会产生不同的结果,这很奇怪。

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

附注文件已就位,第二个代码片段两个文件均已就位。第一个只有目录中的第一个文件,第二个出现错误。

即第一个代码片段 Flask 认为一切正常并继续

最佳答案

os.makedirs接受参数 exist_ok,当该参数为 True 时,如果目录存在,则不会引发错误

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

关于python - 单线程中的 os.mkdir 竞争条件?如何确保在继续之前创建目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59607953/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com