场景:我有很多进程需要通过网络获取文件。如果该文件已经下载,我希望它在磁盘上缓存。如果另一个进程正在下载文件,则阻塞,直到完成下载。如何在Linux中以原子方式创建锁定的文件?
我一直在试图找到最简单的方法来做到这一点。最显而易见的方法是:
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提供的)或者是外部lockfile方法几乎是标准/必需的?
我不知道我是否能以原子创建只有当文件不存在锁定的文件比赛将如何存在。 (条件也是原子)。 O_CREAT |如果文件不存在,则O_EXCL是一个原子创建;我只是想用锁来做到这一点。另一个进程无法开始下载,因为它会检测到文件存在。最后,我不能单独使用打开,因为我必须阻止直到下载完成;在我的解决方案中,我依赖(独占读/写)锁定。 – UsAaR33
你是对的,自动创建和锁定文件将解决您的问题。但这不是fcntl锁定工作的方式,对不起。如果您想使用fcntl锁定,则在您的程序执行任何同步操作之前,您所锁定的文件必须存在。找到一种方法将if()中的创建移动到伪代码之外,或者处理另一个不使用下载文件作为互斥体的同步协议。 –
明白了,所以答案是Linux不提供开放的Windows风格的原子锁。我会坚持使用lockfile方法。 – UsAaR33