首页 > 后端开发 > php教程 > 解决crond脚本执行并发冲突问题

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

WBOY
发布: 2016-06-23 09:09:35
原创
1153 人浏览过

问题

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

<?phpsleep(70);?>
登录后复制

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

*/1 * * * * root php ./test.php
登录后复制

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

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

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

解决方案

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

第一种,代码中控制并发

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

<?php  $lockfile = '/tmp/mytest.lock';    if(file_exists($lockfile)){      exit();  }file_put_contents($lockfile, date("Y-m-d H:i:s"));  sleep(70);unlink($lockfile);  ?>
登录后复制

代码逻辑很简单,这里就不再解释。这种判断文件是否不存在的方式,会有一个问题。那就是有可能程序未执行到最后,也就是没有删除之前创建的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 -hflock (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脚本执行并发冲突问题,转载请注明来源!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板