解决crond脚本执行并发冲突问题

存储架构 2016-06-21

问题

在crond配置脚本执行后,经常会出现重复执行的情况。如下面的脚本:

如果,在crond中的配置项如下:

*/1 * * * * root php ./test.php

就出出现,之前执行的test.php还未结束,新的test.php又被执行。如下:

[hailong@vhost ~]$ ps aux | grep tt.php
56667     5280  0.0  0.0 103388  4432 pts/2    T    08:06   0:00 vim ./test.php
root      5455  0.0  0.1 225288  8812 ?        Ssl  08:08   0:00 /usr/bin/php /home/hailong/test.php
root      5665  5.0  0.1 225288  8748 ?        Ssl  08:09   0:00 /usr/bin/php /home/hailong/test.php
56667     5675  0.0  0.0  69460   852 pts/2    S+   08:09   0:00 grep tt.php

进程一直堆积的话,可能会把系统资源给耗尽,导致系统宕机。

解决方案

解决方案有两种。各有利弊。

第一种,代码中控制并发

这种方法,就是对代码进行改造。增加是否有进程执行的判断。如下面的代码:

代码逻辑很简单,这里就不再解释。这种判断文件是否不存在的方式,会有一个问题。那就是有可能程序未执行到最后,也就是没有删除之前创建的mytest.lock文件。这会导致,之后程序将不能正常执行。

为了解决这个问题,我们对代码进行下改造。不再使用文件是否存在的判断,而是判断进程是否存在。代码修改后如下:

$fp = popen("ps aux | grep 'test.php' | wc -l", "r");
$proc_num = fgets($fp);
if ($proc_num > 3) {
    exit;
}
sleep(70);

这种方式有一个弊端,就是ps命令要写的精确。避免把不是执行test.php脚本的进程也统计到。如:

我们通过vim打开test.php文件。就会导致上面命令误统计。

另外,$proc_num 为什么要大于3而不是大于1,大家可以想想。如果,想不明白,可以加我微信 1798159444。

第二种,使用linux的flock命令

flock命令提供了文件锁的功能。命令参数如下:

[hailong@vhost ~]$ flock -h
flock (util-linux 2.13-pre7)
Usage: flock [-sxun][-w #] fd#
       flock [-sxon][-w #] file [-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
  -h  --help       Display this text
  -V  --version    Display version

使用flock控制并发冲突,我们的crond配置如下:

*/1 * * * * root flock -xn /tmp/mytest.lock -c 'php ./test.php'

其实,使用flock也是有坑的。坑的详细信息,请查看 crond中使用flock命令的坑

原文链接: 解决crond脚本执行并发冲突问题
,转载请注明来源!

责编内容by:博学无忧 (源链)。感谢您的支持!

您可能感兴趣的

PHP package for jQuery Remote Automatic completion I am trying to get remote autocomplete array $items = array( "PR-1001"=>"Product 1", "PR-1002"=>"Product 2" ); Input autocomplete su...
Linux运维之ntpdate同步网络时间 自己的Linux服务器的时间和PC机上的时间不太对,打log的时间对不上,不太方便调式信息的判断,因此需要同步一下Linux服务器的时间和自己Windows的时间,两者一致,才方便调式的查看呢。 同步网络时间 在Linux下,我们可以使用ntpdate进行网络时间的同步,而不是我们...
Java并发指南3:并发三大问题与volatile关键字,CAS操作... 01 final class SetCheck { 02 private int a = 0; 03 private long b = 0; 04 05 void set() { 06 a = 1; 07 b = -1; 08 } 09 10 boolean c...
PHP – Counting the corresponding arrays I have an array structure that looks like this: Array ( => Array ( => image => Array ...
内网渗透之端口转发与代理 *本文作者:Brucetg,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。 理论上,任何接入互联网的计算机都是可访问的,但是如果目标主机处于内网,而我们又想和该目标主机进行通信的话,就需要借助一些端口转发工具来达到我们的目的 注:文中提到的所有工具下载地址 https...