防止 bash(或其他)脚本并行执行的常用方法是在启动时创建锁定目录,在完成时将其删除,并在启动时检查它。但是,可能会出现脚本被异常终止或终止的情况,从而使锁定永久化。
解决这个问题的一种方法是设置一个阈值,任何锁都被认为是陈旧的,如果太早创建应该被忽略。然而,我的 bash 脚本再次调用其他程序,并且可能会被破坏很长时间(而且,也很难分成多个小作品),使得这种方法不可用......
有没有办法解决这个问题?或者还有另一种方法可以锁定脚本以防止并行执行?
防止 bash(或其他)脚本并行执行的常用方法是在启动时创建锁定目录,在完成时将其删除,并在启动时检查它。但是,可能会出现脚本被异常终止或终止的情况,从而使锁定永久化。
解决这个问题的一种方法是设置一个阈值,任何锁都被认为是陈旧的,如果太早创建应该被忽略。然而,我的 bash 脚本再次调用其他程序,并且可能会被破坏很长时间(而且,也很难分成多个小作品),使得这种方法不可用......
有没有办法解决这个问题?或者还有另一种方法可以锁定脚本以防止并行执行?
除了锁目录,你还可以保存持有锁的实例的进程ID。如果另一个实例发现自己被阻塞,它可以检查该进程 ID 以查看它是否仍在运行,如果没有,则删除锁定目录和 PID 记录,然后尝试重新获取锁定。
编辑说明:使用文件系统的底层序列化属性来实现更高级别的同步是一种常见的方法——非常适合快速而肮脏的解决方案,或者如果您绝对必须在 shell 脚本中完成整个事情。如果您需要比这更防弹的东西,TCP/IP 可能会提供一种不那么脆弱、更便携的方法。您可以用 C(或几乎任何其他语言)编写一个轻量级 TCP/IP 服务器:它只是在某个端口上侦听应用程序启动请求(单线程,一次一个连接,让 TCP 层解决所有竞争条件),同时监视正在进行的作业以查看何时接受新请求。
我的第一个想法是编写足够多的 C 来使用 Linux 调用,例如flock(),这些调用会在进程死亡时自动释放。为了刷新我的记忆,我在http://linux.die.net/man/1/flock上找到了关于“flock - 从 shell 脚本管理锁”的信息 - 如果你可以访问这个,我会使用它。如果没有,类似的东西可能相当容易实现。