【发布时间】:2021-05-21 17:39:18
【问题描述】:
假设我有一个 bash 脚本,我在给定时间最多需要一个实例。假设多次调用同一个 bash 脚本的预期行为是将它们的执行排队。
在脚本类似于函数的单个程序中,这可以通过互斥锁来实现。
我将如何处理这样的设计?
【问题讨论】:
标签: bash concurrency thread-safety
假设我有一个 bash 脚本,我在给定时间最多需要一个实例。假设多次调用同一个 bash 脚本的预期行为是将它们的执行排队。
在脚本类似于函数的单个程序中,这可以通过互斥锁来实现。
我将如何处理这样的设计?
【问题讨论】:
标签: bash concurrency thread-safety
好吧,就这样吧……
在脚本中实现排队系统。
让脚本尝试mkdir 一个已知的标准目录名称。
if mkdir /tmp/${0##*/}.Q
then : .. proceed normally
mkdir 是原子的,所以只有一个实例可以成功。
如果失败,请测试是否是因为该目录已存在。
如果没有,则有问题,报告并中止。
如果成功,则在以脚本的 PID 命名的目录中打开一个 FIFO,并在其中写入其命令行参数。也许添加 PID。
然后清除 args、fork 一个孩子和wait。在 SIGCHLD 上再次读取 FIFO。只要你找到东西,起泡/冲洗/重复。当没有更多时,关闭。
如果使用 args 运行但 dir 存在,则确认副本已在另一个 PID 上运行,在 dir 中找到 FIFO,将 args(可能是 PID)写入其中,然后退出。
如果它没有 args(可能是因为它是一个分叉的孩子),读取管道,设置args,然后处理它们。确认有一个副本正在运行,其 PID 与 FIFO 匹配。处理完所有记录后,删除FIFO并正常退出。
根本没有测试过这个。期待发现一些缺陷。
OR 只需查找“标志文件”并在循环中休眠一段时间,直到它不存在,然后创建它,正常运行,完成后再次删除它。这并不能保证订单,但它确实可以防止运行多个副本。
【讨论】:
flock,但until mkdir foo; do 应该可以正常工作。