场景:我有许多进程正在运行,需要通过网络获取文件。如果文件已经下载,我希望它缓存在磁盘上。如果另一个进程正在下载该文件,则阻塞直到它完成下载。
我一直在努力寻找最简单的方法来做到这一点。显而易见的方法是:
create file w/ an exclusive lock active on it only if it doesn't exist (O_CREAT | O_EXCL)
if file exists already:
open file and acquire exclusive lock
else:
download to newly created file
release lock
这个系统在(看似)没有竞争条件的情况下实现了上述目标
不幸的是,我找不到关于如何使用 open() 等来创建在 Linux 中被锁定的文件的文档。如果我将创建步骤拆分为:
open w/ O_CREAT | O_EXCL
flock
现在在创建和锁定之间存在竞争条件(非创建进程在创建者之前获得锁)。
我意识到我可以为每个文件使用一个外部锁定文件(例如文件名 + '.lock),这是我在尝试创建文件名之前获得的,但这感觉.. 不雅(我现在需要担心如何归档实际上有一个 .lock 后缀!)
无论如何,是否可以自动创建和锁定它(如 Windows 提供的那样),或者外部锁定文件方法几乎是标准/必需的?
最佳答案
种族无论如何都存在。如果该文件可能存在也可能不存在,那么您必须在尝试锁定它之前测试它是否存在。但是,如果 file 是您的互斥锁,那么您就不可能这样做,并且“如果文件已经存在”(false)和“下载到新创建的文件”之间的空间是不受限制的。另一个进程可能会在您开始下载之前创建文件并开始下载,您会破坏它。
这里基本上不用fcntl锁,利用文件本身的存在。如果文件已经存在,使用 O_CREAT 和 O_EXCL 的 open()
将失败,告诉您其他人先到达那里。
关于linux - 我如何在 Linux 中自动创建一个锁定的文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17352655/