项目中难免会有任务要定时执行,我们的解决办法,搭建一套调度系统或在系统(linux)上执行crontab,我们来讲下crontab下执行时间较长的任务,如何避免多次执行引发的冲突。
问题:假设我们要执行300次循环,每次休眠1秒,而我们的定时任务是1分钟执行一次。
<?
for($i=0; $i<100; $i++)
{
echo date('Y-m-d H:i:s')."\r\n";
sleep(1);
}
?>
定时任务:
#执行100次循环
*/1 * * * * root /www/web/bin/php /www/web/test.php >> /tmp/test.log
出现的结果在下一分钟执行时,由于当前的任务没执行完,出现了多次执行的问题,与想要的效果想差甚远。
到这里,可能会说,在上面的代码中加锁
<?php
$fp = fopen("/tmp/lock.txt", "r+");
if (flock($fp, LOCK_EX)) { // 进行排它型锁定
ftruncate($fp, 0); // truncate file
for($i = 0 ; $i < 100; $i++)
{
echo date('Y-m-d H:i:s')."\r\n";
sleep(1);
}
fflush($fp); // flush output before releasing the lock
flock($fp, LOCK_UN); // 释放锁定
} else {
echo "Couldn't get the lock!";
}
fclose($fp);
?>
其实,不用这么麻烦,我们只要使用上linux自带的flock即可
我们看到启动了3个进程,很是好奇,可以安装pstree来查看 yum -y install psmisc
最后我们来看看flock的参数结束这篇文章
[root@fjr-ofckv-74-179 tmp]# flock --help
Usage:
flock [options] <file|directory> <command> [command args]
flock [options] <file|directory> -c <command>
flock [options] <file descriptor number>
Options:
-s --shared get a shared lock //获取一个共享锁
-x --exclusive get an exclusive lock (default) //获取一个排他锁
-u --unlock remove a lock //释放锁
-n --nonblock fail rather than wait //失败后等待还是返回,其实就是nio或bio
-w --timeout <secs> wait for a limited amount of time //超时
-E --conflict-exit-code <number> exit code after conflict or timeout //异常或超时退出
-o --close close file descriptor before running command
-c --command <command> run a single command string through the shell
-h, --help display this help and exit
-V, --version output version information and exit
For more details see flock(1).