摘要1:https://www.cnblogs.com/zhaojingyu/p/8955851.html
摘要2:https://www.cnblogs.com/wangxusummer/p/4933492.html
摘要3:https://blog.csdn.net/weixin_33753003/article/details/93229004

用flock命令解决Linux计划任务重复执行
在做计划任务的时候,可能由于某些问题,任务没有执行完成,导致任务重复的运行,解决这个问题,只需要一个flock命令就可以了。

flock参数

  • flock --help
  • flock (util-linux-ng 2.17.2)
  • Usage: flock [-sxun][-w #] fd#
  • flock [-sxon][-w #] file [-c] command…
  • flock [-sxon][-w #] directory [-c] command…
  • -s --shared Get a shared lock #获得一个共享锁
  • -x --exclusive Get an exclusive lock #获得一个独占锁,这是默认的
  • -u --unlock Remove a lock #删除一个锁,通常是不需要的,因为在文件关闭时锁会自动删除
  • -n --nonblock Fail rather than wait #如果没有立即获得锁,直接失败而不是等待
  • -w --timeout Wait for a limited amount of time #如果没有立即获得锁,等待指定时间
  • -o --close Close file descriptor before running command #在执行命令之前关闭保持锁的文件描述符
  • -c --command Run a single command string through the shell #在shell中运行一个单独的命令
  • -h --help Display this text #显示帮助
  • -V --version Display version #显示版本

flock文件锁的使用

1.创建sh文件
vim test.sh

#! /bin/bash
echo "Hello World"
sleep 10

2.创建锁文件
touch test.lock #随便命名

[root@localhost ~]# flock -xn ./test.lock -c "sh /root/test.sh"

运行中…

3.开启另外一个bash窗口运行

[root@localhost ~]# flock -xn ./test.lock -c "sh /root/test.sh"

前面未获取到锁直接返回 直到其他运行完毕 这个才开始运行
4.crontab运用flock防止重复执行

* * * * * * (flock -xn ./test.lock -c "sh /root/test.sh")  #-n 为非阻塞模式

crontab配置nginx

1.机器down机自动启动或重启
可以在daemon开始的时候, 打开一个文件然后获取一个写锁. 守护脚本也打开文件并设置写锁, 然后阻塞, 一旦写锁获得成功, 则说明daemon已经挂了. 此时守护脚本重启daemon并放弃写锁.
运行

flock -x ./test.lock -c "/usr/local/nginx/sbin/nginx" #去掉-n表示使用阻塞模式

运行中…

2.再次执行

flock -x ./test.lock -c "/usr/local/nginx/sbin/nginx" #去掉-n表示使用阻塞模式

阻塞中…

3.模拟down机

[root@localhost ~]# ps aux |grep "nginx"|grep"master"|grep -v "grep"|awk'{print $2}'|xargskill -9

kill后阻塞的命令马上执行 新的进程PID立马产生 欧啦

flock在文件操作符中运用

linux在多个进程同时操作同一份文件的时候,很容易导致文件混乱,这时候就需要锁,来保证文件的完成性.

flock主要三种操作类型:

  • lock_sh,常被用作读共享锁;
  • LOCK_EX,只能被一个进行使用,常被用作写锁;
  • LOCK_UN,释放锁;
 public function logResult($word='') {
        $fp = fopen("log.txt","a");
        flock($fp, LOCK_EX) ;//进程会被阻塞,直到锁被释放掉
        fwrite($fp,"执行日期:".strftime("%Y%m%d%H%M%S",time())."\n".$word."\n");
        flock($fp, LOCK_UN);
        fclose($fp);
    }

使用共享锁LOCK_SH,如果是读取,不需要等待,但如果是写入,需要等待读取完成。

使用独占锁LOCK_EX,无论写入/读取都需要等待。
LOCK_UN,无论使用共享/读占锁,使用完后需要解锁。
LOCK_NB,当被锁定时,不阻塞,而是提示锁定。

Logo

更多推荐