在shell中实现排它锁以避免脚本重复执行

在linux中,我们经常会用到crontab定时执行一些脚本,但脚本的执行时间往往无法控制,当脚本执行时间过长时,可能会导致上一次任务的脚本还没执行完,下一次任务的脚本又开始执行了。这种情况下可能会出现一些并发问题,严重时会导致出现脏数据/性能瓶颈的恶性循环。

针对这个问题,可以使用linux的flock来解决,flock支持共享锁和排它锁,如果一个进程对某个加了排他锁,则其它进程无法加锁,可以选择等待超时或马上返回。

具体可以参考以下两篇文章:
Linux 2.6 中的文件锁
flock——Linux 下的文件锁

我在我的CentOS 5.8上做了一个简单的测试:

1.准备一个file-lock-test.sh脚本:
引用

#/bin/bash

echo ""
echo "---------------------------------"
echo "start at `date '+%Y-%m-%d %H:%M:%S'`..."

sleep 140s

echo "finished at `date '+%Y-%m-%d %H:%M:%S'`..."


2.测试排它锁
在crontab中定义如下一个定时任务(每分钟执行一次)
引用

* * * * * flock -xn /dev/shm/test.lock -c "sh /opt/gaosong/file-lock-test.sh >> /opt/gaosong/stdout.log"

输出日志文件如下:
引用

---------------------------------
start at 2013-08-09 11:36:01... #获取到锁
finished at 2013-08-09 11:38:21... #此时释放所

---------------------------------
start at 2013-08-09 11:39:01...         #11:38:00启动的定时任务由于拿不到锁,所以马上退出了,导致11:39:00才能拿到锁
finished at 2013-08-09 11:41:21...


3.测试排它锁+等待超时
将定时任务改为:
引用

* * * * * flock -x -w 30 /dev/shm/test.lock -c "sh /opt/gaosong/file-lock-test.sh >> /opt/gaosong/stdout.log"

输出日志文件如下:
引用

---------------------------------
start at 2013-08-09 11:42:01...
finished at 2013-08-09 11:44:21...

---------------------------------
start at 2013-08-09 11:44:21... #11:44:00启动的定时任务等待了20秒后,上一个任务释放了锁,所以此任务可以马上拿到锁,并继续执行
finished at 2013-08-09 11:46:41...

你可能感兴趣的:(linux,flock)