gpt4 book ai didi

linux - 我可以使用带有 O_CREAT 和 flock(2) 的 open(2) 来防止脚本启动两次吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:16:01 24 4
gpt4 key购买 nike

我想通过使用 PID 文件来防止脚本启动两次。有很多方法可以实现排他性,但由于我的脚本将始终在 Linux 机器上运行,并且我希望能够自动检测过时的 PID 文件,所以我想使用 flock(2) 来实现这个。

很久以前,一位同事告诉我,以下伪代码是执行此操作的正确方法(open(..., 'w') 表示“使用 在写入模式下打开” O_CREAT"):

fd = open(lockfile, 'w');
write(fd, pid);
close(fd);
fd = open(lockfile);
flock(fd)
file_pid = read(fd)
if file_pid != pid:
exit(1)
// do things

我很好奇为什么他建议用上面的而不是:

fd = open(lockfile, 'w')
flock(fd)
// do things

大概他提出这个建议是因为他认为 open(2)O_CREAT 的“如果文件不存在则创建”功能不是原子的,也就是说,两个完全同时调用 open(2) 的进程可能会获得两个不同文件的句柄,因为文件创建不是独占的。

我的问题是,后面的代码在 Linux 系统上是否总是正确的,或者如果不是,什么时候不正确?

最佳答案

flock 并非 100% 可靠:http://en.wikipedia.org/wiki/File_locking#Problems

从某种意义上说,第一个配方相当具有侵入性,因为进程的后续调用可能会盲目地覆盖先前调用写入的 pid 数据,从而有效地阻止第一个进程运行。因此,在高重复调用率下,可能没有进程运行。

要确保文件创建独占性,请使用 O_CREAT | O_EXCL。不过,您需要处理过早的进程死亡而将文件留在后面。

我建议 2 个文件:

  • 用 O_CREAT 打开的锁文件 | O_EXCL,仅用于保护实际的 PID 文件操作,应该只存在很短的时间,很容易根据创建时间判断是否过时。
  • 实际的PID文件

每个进程等待锁文件消失(当它变得陈旧时清理它),然后尝试创建锁文件(只有一个实例成功,其他实例等待),检查 PID 文件存在/内容(清理并如果陈旧则删除它),如果它决定运行,则创建一个新的 PID 文件,然后删除锁定文件并根据决定运行/退出。

关于linux - 我可以使用带有 O_CREAT 和 flock(2) 的 open(2) 来防止脚本启动两次吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29979624/

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