zoukankan      html  css  js  c++  java
  • flock防止crontab脚本周期内未执行完重复执行(转)

    如果某脚本要运行30分钟,可以在Crontab里把脚本间隔设为至少一小时来避免冲突。而比较糟的情况是可能该脚本在执行周期内没有完成,接着第二个脚本又开始运行了。如何确保只有一个脚本实例运行呢?一个好用的方法是利用lockf(FreeBSD 8.1下为lockf,CentOS 5.5下为flock),在脚本执行前先检测能否获取某个文件锁,以防止脚本运行冲突。

    lockf的参数如下。

    -k:一直等待获取文件锁。

    -s:silent,不发出任何信息,即使拿不到文件锁。

    -t seconds:设定timeout的时间是seconds秒,如果超过时间,则自动放弃。

    以下Crontab计划任务执行前,需获取临时文件create.lock的文件锁,此项Crontab计划任务的内容如下:

    
    
    1. */10 * * * * (lockf -s -t 0 /tmp/create.lock /usr/bin/python /home/project/cron/create_tab.py  
    2. >> /home/project/logs/create.log 2>&1) 

    若第一个实例在10分钟内没有运行完,第2个实例不会运行。我以前是通过Shell脚本来解决这个问题的,比如用while...do循环,然后放在后台执行。但后来发现其实用flock或lockf方法更为简单。

    ==============================

    crontab防止脚本周期内未执行完重复执行

    个人体会: flock -xn my.lock commond
    my.lock是一个文件,应该可以是任意文件,可以新建一个空文件
    当flock 获得锁后就会执行后面的 commond
    测试过程: $1: flock -xn my.lock sleep 20
                  $2: flock -xn my.lock ls
    只有当1返回后, 2的ls才会成功

    crontab防止脚本周期内未执行完重复执行

    如果某脚本要运行30分钟,可以在Crontab里把脚本间隔设为至少一小时来避免冲突。而比较糟的情况是可能该脚本在执行周期内没有完成,接着第 二个脚本又开始运行了。如何确保只有一个脚本实例运行呢?一个好用的方法是利用lockf(FreeBSD 8.1下为lockf,CentOS  5.5下为flock),在脚本执行前先检测能否获取某个文件锁,以防止脚本运行冲突。

    lockf的参数如下。

    -k:一直等待获取文件锁。

    -s:silent,不发出任何信息,即使拿不到文件锁。

    -t seconds:设定timeout的时间是seconds秒,如果超过时间,则自动放弃。

    以下Crontab计划任务执行前,需获取临时文件create.lock的文件锁,此项Crontab计划任务的内容如下:

    1
    */10 * * * * (lockf -s -t 0 /tmp/create.lock /usr/bin/python /home/project/cron/create_tab.py  >> /home/project/logs/create.log 2>&1)

    若第一个实例在10分钟内没有运行完,第2个实例不会运行。我以前是通过Shell脚本来解决这个问题的,比如用while...do循环,然后放在后台执行。但后来发现其实用flock或lockf方法更为简单。

    附上linux下的flock的用法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    flock (util-linux 2.13-pre7)
    Usage: flock [-sxun][-w #] fd#
           flock [-sxon][-w #] file [-c] command...
      -s  --shared     Get a shared lock 
    #共享锁,在定向为某文件的FD上设置共享锁而未释放锁的时间内,其他进程试图在定向为此文件的FD上设置独占锁的请求失败,而其他进程试图在定向为此文件的FD上设置共享锁的请求会成功
      -x  --exclusive  Get an exclusive lock 
    #独占或排他锁,在定向为某文件的FD上设置独占锁而未释放锁的时间内,其他进程试图在定向为此文件的FD上设置共享锁或独占锁都会失败。只要未设置-s参数,此参数默认被设置
      -u  --unlock     Remove a lock 
    #手动解锁,一般情况不必须,当FD关闭时,系统会自动解锁,此参数用于脚本命令一部分需要异步执行,一部分可以同步执行的情况
      -n  --nonblock   Fail rather than wait 
    #为非阻塞模式,当试图设置锁失败,采用非阻塞模式,直接返回1,
      -w  --timeout    Wait for a limited amount of time
    #设置阻塞超时,当超过设置的秒数,就跳出阻塞,返回1
      -o  --close      Close file descriptor before running command
      -c  --command    Run a single command string through the shell 执行其后的comand
      -h  --help       Display this text
      -V  --version    Display version

    举个例子执行如下脚本:

    每天23:30的时候执行一个脚本,但是执行前必须要获得排他文件锁,否则无法执行命令

    1
    30 23 * * * flock -xn /tmp/test.lock -c '/usr/local/php test.php'

    ==========================================================================

    如果在crontab里有个定时任务设置为一分钟执行一次,但是它执行的时间可能会超过一分钟,此时crontab一分钟后会再次运行该脚本,这样就会出现冲突,如果程序不做容错处理,可能会导致出现一些问题。如果想解决这个问题,可以用Linux中的进程锁控制crontab执行的并发问题。

    image

    在crontab设置lock

    */5 * * * * /usr/bin/flock -xn /var/run/up_svn.lock -c'/scripts/up_svn.sh >/dev/null2>&1'

    显示如下:

    image

  • 相关阅读:
    Android 手机摇一摇功能的实现
    Android 只开启一个Activity实例
    android 获取Datepicker日期
    帧动画
    进度条ProgressDialog
    AlertDialog错误
    ListView加checkBox可以实现全选等功能
    一些自己常用的工具类
    错层
    Parallax
  • 原文地址:https://www.cnblogs.com/sandea/p/9592235.html
Copyright © 2011-2022 走看看