gpt4 book ai didi

python - Python 中的竞争条件创建文件夹

转载 作者:太空狗 更新时间:2023-10-29 16:53:36 24 4
gpt4 key购买 nike

我有一个 urllib2 缓存模块,它偶尔会因为以下代码而崩溃:

if not os.path.exists(self.cache_location):
os.mkdir(self.cache_location)

问题是,第二行执行的时候,文件夹可能已经存在,会报错:

  File ".../cache.py", line 103, in __init__    os.mkdir(self.cache_location)OSError: [Errno 17] File exists: '/tmp/examplecachedir/'

这是因为脚本被我无法控制的第三方代码同时启动了很多次。

可以找到代码(在我尝试修复错误之前)here, on github

我无法使用 tempfile.mkstemp ,因为它通过使用随机命名的目录 ( tempfile.py source here ) 来解决竞争条件,这将破坏缓存的目的。

我不想简单地丢弃错误,因为如果文件夹名称作为文件存在(不同的错误),则会引发相同的错误 Errno 17 错误,例如:

$ touch blah$ python>>> import os>>> os.mkdir("blah")Traceback (most recent call last):  File "", line 1, in OSError: [Errno 17] File exists: 'blah'>>>

我无法使用 threading.RLock,因为代码是从多个进程调用的。

因此,我尝试编写一个简单的基于文件的锁(that version can be found here),但这有一个问题:它创建了上一层的锁文件,所以 /tmp/example.lock for /tmp/example/,如果您使用 /tmp/ 作为缓存目录(因为它试图制作 /tmp.lock),它会中断。 .

简而言之,我需要将 urllib2 响应缓存到磁盘。为此,我需要以多进程安全方式访问已知目录(如果需要,创建它)。它需要在 OS X、Linux 和 Windows 上运行。

想法?我能想到的唯一替代解决方案是使用 SQLite3 存储而不是文件重写缓存模块。

最佳答案

代替

if not os.path.exists(self.cache_location):
os.mkdir(self.cache_location)

你可以做

try:
os.makedirs(self.cache_location)
except OSError:
pass

因为您最终会得到相同的功能

免责声明:我不知道这可能有多 Pythonic。


使用 SQLite3可能有点矫枉过正,但会为您的用例增加很多功能和灵 active 。 p>

如果你必须做大量的“选择”、并发插入和过滤,那么使用 SQLite3 是个好主意,因为它不会比简单的文件增加太多复杂性(这可能是有争议的它消除了复杂性)。


重读你的问题(和评论)我可以更好地理解你的问题。

文件产生相同竞争条件的可能性有多大?

如果它足够小,那么我会做类似的事情:

if not os.path.isfile(self.cache_location):
try:
os.makedirs(self.cache_location)
except OSError:
pass

另外,阅读你的代码,我会改变

else:
# Our target dir is already a file, or different error,
# relay the error!
raise OSError(e)

else:
# Our target dir is already a file, or different error,
# relay the error!
raise

因为这确实是您想要的,Python 重新引发完全相同的异常(只是吹毛求疵)


还有一件事,可能是this可能对你有用(仅限类 Unix)。

关于python - Python 中的竞争条件创建文件夹,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1586648/

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