我已安排一个 cron 作业每分钟运行一次,但有时脚本需要一分钟以上的时间才能完成,我不希望作业开始“堆积”在一起。我猜这是一个并发问题 - 即脚本执行需要相互排斥。
为了解决这个问题,我让脚本寻找特定文件的存在(“锁文件.txt“) 并且如果存在则退出,touch
如果不存在则退出。但这是一个非常糟糕的信号量!是否有我应该知道的最佳实践?我应该编写一个守护进程吗?
答案1
有几个程序可以自动执行此功能,消除了自己执行此操作带来的烦恼和潜在错误,并且通过在后台使用 flock 也避免了陈旧的锁定问题(如果您只使用 touch,则存在风险)。我过去曾使用过lockrun
和,但现在有(1)(在较新版本的 util-linux 中),它很棒。它真的很容易使用:lckdo
flock
* * * * * /usr/bin/flock -n /tmp/fcj.lockfile /usr/local/bin/frequent_cron_job
答案2
在 shell 中最好的方法是使用羊群(1)
(
flock -x -w 5 99
## Do your stuff here
) 99>/path/to/my.lock
答案3
实际上,flock -n
可以代替lckdo
*,因此您将使用来自内核开发人员的代码。
构建于沃姆布尔的例子,你可以这样写:
* * * * * flock -n /some/lockfile command_to_run_every_minute
顺便说一句,查看代码,、flock
和lockrun
都lckdo
做同样的事情,所以这只是一个最容易获得的问题。
答案4
您尚未指定是否希望脚本等待上一次运行完成。通过“我不希望作业开始‘堆叠’在一起”,我猜您的意思是如果脚本已经在运行,则希望脚本退出,
因此,如果您不想依赖 lckdo 或类似的东西,您可以这样做:
PIDFILE=/tmp/`basename $0`.pid
if [ -f $PIDFILE ]; then
if ps -p `cat $PIDFILE` > /dev/null 2>&1; then
echo "$0 already running!"
exit
fi
fi
echo $$ > $PIDFILE
trap 'rm -f "$PIDFILE" >/dev/null 2>&1' EXIT HUP KILL INT QUIT TERM
# do the work