Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 我是否可以防止脚本使用open(2)和O_CREAT和flock(2)启动两次?_Linux_Unix_Daemon - Fatal编程技术网

Linux 我是否可以防止脚本使用open(2)和O_CREAT和flock(2)启动两次?

Linux 我是否可以防止脚本使用open(2)和O_CREAT和flock(2)启动两次?,linux,unix,daemon,Linux,Unix,Daemon,我想通过使用PID文件防止脚本启动两次。实现独占性的方法有很多,但由于我的脚本将始终在Linux机器上运行,并且我希望能够自动检测过时的PID文件,因此我希望使用flock(2)来实现这一点 很久以前,一位同事告诉我,下面的伪代码是正确的方法(open(…,'w')的意思是“使用O_create以写模式打开”): 我很好奇,为什么他提出上述建议,而不是: fd = open(lockfile, 'w') flock(fd) // do things 他提出这一点大概是因为他认为open(2)与

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

很久以前,一位同事告诉我,下面的伪代码是正确的方法(
open(…,'w')
的意思是“使用
O_create
以写模式打开”):

我很好奇,为什么他提出上述建议,而不是:

fd = open(lockfile, 'w')
flock(fd)
// do things
他提出这一点大概是因为他认为
open(2)
O_create
的“如果不存在则创建文件”功能不是原子的,也就是说,两个同时调用
open(2)
的进程可能会得到两个不同文件的句柄,因为文件创建不是独占的


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

flock不是100%可靠的:

第一个配方相当具有侵入性,因为随后的流程调用可能会盲目地覆盖前一个调用写入的pid数据,从而有效地阻止第一个流程运行。因此,在高重复调用率下,所有进程都不可能运行

为了确保文件创建的排他性,请使用O|u CREAT | O|u EXCL。您需要处理进程过早死亡而留下文件,tho

我建议使用两种文件:

  • 使用O|u CREAT | O|u EXCL打开的锁文件(仅用于保护实际的PID文件操作)应该只存在很短的时间,很容易根据创建时间确定是否过时
  • 实际的PID文件

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

谢谢您的回答,这是一个很好的解决方案。你知道关于用O_CREAT打开但没有O_EXCL的部分的答案吗?如中所述,假设flock是可靠的,第二个伪代码段可以工作吗?它最多只能序列化多个实例的执行,但不能阻止后续执行,如果没有O_EXCL,后续执行将在flock阻塞,并在第一个进程出于任何原因退出时继续。我很难实现一个可靠的逻辑。您的解决方案类似于perl
File::NFSLock
,我有时会使用它来编写,它是否同时会导致NFS缓存无效?我不能100%确定,如果尝试读取正在创建的文件以外的其他文件,是否仍会使用缓存。缓存的目录条目可以通过在该目录中创建一个文件来刷新(至少我的观察结果似乎支持这一点)。它还可能取决于实际的客户端和/或服务器NFS实现。除此之外,
flock()。这段代码似乎在文件中写入新进程的PID,即使旧进程可能仍在使用它。这本身就造成了悲伤。我还没有在这里找到一个好的“如何锁定”Q&a,这有点令人惊讶,尽管我只查找了“lockfile”,所以我不能说我已经彻底搜索过了。只要你不希望该文件包含当前拥有锁的进程的确切pid,代码应该是正确的。我不知道你所说的“监督锁”是什么意思,你是说“咨询锁”吗?如果你是这个意思,只要这两个进程都是群集的,它就不重要了()。在什么情况下会发生错误的事情(两个进程将同时到达伪代码的第9行)?对于我的“监督”,请使用“咨询”-抱歉使用了错误的术语。锁定文件的整个要点是包含锁定文件的进程的PID,这样,锁文件的读取器就可以检查进程是否仍然存在,如果不存在,就接管锁。所以,在文件中输入错误的PID是一种精神错乱。维基百科似乎会说我陈述的情况太多了。然而,这一部分有点站不住脚(例如,它没有给出伪代码算法),而且肯定有很多方法可以使用锁文件进行锁定——不一定都像其他方法那样有效或有弹性。
fd = open(lockfile, 'w')
flock(fd)
// do things