`
blueswind8306
  • 浏览: 124558 次
  • 来自: ...
社区版块
存档分类
最新评论

在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...

0
0
分享到:
评论
2 楼 blueswind8306 2013-08-14  
lionfox 写道
如果用进程id &进程名字 结合ps -ef | grep id | grep name|wc -l
这样是不是也可以呢


这样有并发问题,类似如下伪代码:
pid=`cat pidfile`
process=`ps -ef |grep $pid |grep name|wc -l`
if [ $process -eq 0 ]; then
  echo $$ > pidfile
  do something...
fi


如果同时有两个进程同时执行到if判断这行,可能两个进程都得到true的结果,这时候就会出现同时执行的情况,并且后一个进程会覆盖写入前一个进程的pidfile。

但对于flock命令则不同,它会直接尝试对某个文件加锁,并且加锁操作是原子的,这样如果进程1加锁成功,进程2就一定加锁失败并返回(或者阻塞等待锁释放)。
具体可以参考:Linux 2.6 中的文件锁这篇文章的“Linux 中关于文件锁的系统调用”这段
1 楼 lionfox 2013-08-09  
如果用进程id &进程名字 结合ps -ef | grep id | grep name|wc -l
这样是不是也可以呢

相关推荐

    IDEA中编写并运行shell脚本的实现

    主要介绍了IDEA中编写并运行shell脚本的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    Shell脚本中获取进程ID的方法

    当我在执行shell脚本时,它会启动一个叫子shell的进程。作为主shell的子进程,子shell将shell脚本中的命令作为批处理运行(因此称为“批处理进程”)。 在某些情况下,你也许想要知道运行中的子shell的PID。这个PID...

    shell脚本实现文件锁功能

    主要介绍了shell脚本实现文件锁功能,本文实现了一个排它锁,从而实现避免脚本重复执行,需要的朋友可以参考下

    LinuxShell脚本学习基础视频

    资源名称:Linux Shell脚本学习基础视频资源目录:【】11a00d99b60c4e2eba3440b8aa3a6bdd【】linux_shell脚本编程_01认识shell,如何编写shell脚本和执行【】linux_shell脚本编程_02vivim简单的常用操作【】linux_...

    shell脚本实现服务器进程监控的方法

    主要介绍了shell脚本实现服务器进程监控的方法,非常不错,具有参考借鉴价值,需要的朋友参考下吧

    Shell脚本实现从文件夹中递归复制文件

    主要介绍了Shell脚本实现从文件夹中递归复制文件,本文脚本实现从十层左右的文件夹中复制所有文件到一目录中,需要的朋友可以参考下

    shell脚本写的加密脚本

    学习shell脚本,了解linux知识。

    linux下shell脚本实现数据的导出

    第一次接触linux系统,之前写的数据导出不好使了。...找了好多资料,最后决定写个shell脚本;没接触过shell脚本,网上大部分例子都写的挺复杂的;贴个简单的,不带传参什么的;只是最简单的数据表的导出备份

    shell 并行运行脚本

    通过循环、队列、fifo文件,实现shell并行任务运行的脚本,测试环境为CentOS7

    shell执行mysql脚本

    在shell脚本中向SQL文件传递参数,并且在shell脚本中执行SQL文件。

    shell 脚本shell 脚本shell 脚本

    shell 脚本shell 脚本shell 脚本shell 脚本shell 脚本shell 脚本shell 脚本shell 脚本shell 脚本shell 脚本shell 脚本

    Shell脚本避免重复执行的方法

    # 检查通过sh命令执行的shell脚本是不是还在执行当中,避免重复执行. # 把这段代码放在需要保证唯一性的程序头部即可 # 注意,如果直接把此脚本放到cron里面执行的话,必须再grep -v ” -c sh “以排除由cron产生的...

    让shell脚本在后台执行

    使用shell脚本管理系统,可将脚本放在后台执行,同时非挂起运行。

    android系统中调用shell脚本

    网上看了好多android下调用脚本的例子,在没有root的情况下,大多只能执行一些简单的脚本命令,经验证,总结出一种还算比较有用的方法,可以较多数脚本,算是比较靠谱,共享下

    Shell脚本实现二维码图片生成

    这个shell脚本是我在工作中开发的,适合在旧有系统,无源码但又希望实现二维码打印功能的系统

    hbase-shell批量命令执行脚本的方法

    批量执行hbase shell 命令 #!/bin/bash source /etc/profile ...以上这篇hbase-shell批量命令执行脚本的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持软件开发网。

    从Linux程序中执行shell(程序、脚本)并获得输出结果

    通常在程序中通过 system函数来调用shell命令。但是,system函数仅返回命令是否执行成功,而我们可能需要获得shell命令在控制台上输出的结果。例如,执行外部命令ping后,如果执行失败,我们希望得到ping的返回信息...

    Logcat及adb shell命令的bat脚本实现例子

    运用bat脚本打包logcat、adb shell语句等代码,并克服了进入shell后后续代码无法执行的问题

    shell 脚本 实例 shell 脚本 实例

    参考shell脚本实例.rar参考shell脚本实例.ra参考shell脚本实例.rarr

Global site tag (gtag.js) - Google Analytics