Home > Backend Development > PHP Tutorial > crond中使用flock命令的坑

crond中使用flock命令的坑

WBOY
Release: 2016-06-23 09:09:34
Original
1164 people have browsed it

现象

需要定期去执行一个PHP脚本,首先想到的是通过crond命令来实现这个功能。但是,在crond的执行过程中发现一个诡异的事情。在crond中的配置如下。

*/1 * * * * root /usr/bin/flock -xn /tmp/test.lock -c '/usr/bin/php /home/hailong/test.php > /tmp/test.tt 2>&1'
Copy after login

脚本只会在第一次成功执行,之后就不会再执行。当删除/tmp/test.lock文件后,PHP脚本又能正常执行了。执行完一次后,就又不能正常执行了。

题外话:

大家看到,配置文件最后增加了 2>&1。为啥要加2>&1呢?请查看博文《 一个echo引起的进程崩溃》

另外,细心的朋友也会发现,我们使用了flock命令。使用flock命令是为了防止脚本被并发重复执行。更多控制crond脚本并发重复执行的方法,请查看《 解决crond脚本执行并发冲突问题》

分析

把crond配置中把flock去掉。如下:

*/1 * * * * root /usr/bin/php /home/hailong/test.php > /tmp/test.tt 2>&1
Copy after login

发现脚本可以正常执行了。那必定是flock的问题。flock作为一个成熟的linux命令,有问题的可能性不大。最大的可能性就是PHP代码中某部分代码和flock冲突。PHP代码如下:

<?php$f = popen("/home/exfilter restart", "r");while(!feof($f)) {    $content = fgets($f, 1024);    if (strpos($content, "start success") !== false) {        break;    }}pclose($f);file_put_contents("/tmp/test.log", date("Y-m-d H:i:s"));?>
Copy after login

之前说过,只有第一次,flock的锁文件不存在的时候,才能正常执行。当锁文件存在后,就不再正常执行。PHP程序执行完毕后,flock并没有释文件锁。那我们看下,/tmp/test.lock文件是被那个文件所占用。

[hailong@vhost ~]$ sudo /usr/sbin/lsof | grep test.lockexfilter  29821        root    3r      REG              202,1           0   90439710 /tmp/test.lock[hailong@vhost ~]$ ps aux | grep 29821root     29821  0.1  0.2 175224 22596 ?        Ssl  07:46   0:00 /home/exfilter -d56667    30068  0.0  0.0  69460   852 pts/0    S+   07:49   0:00 grep 29821
Copy after login

可见,test.lock文件正是被PHP程序中popen函数启动的进程所占用。由于,启动的是一个守护进程,进程不退出,锁一直被占用。

解决方法

启用flock命令,改用其他方法。更多方法请查看博文《 解决crond脚本执行并发冲突问题》

延伸阅读

Linux系统上的文件锁主要分为协同锁(advisory lock)和强制锁(mandatory lock)。在Linux上使用的文件锁大部分为协同锁,而且使用强制锁的时候也要检查系统是否支持强制锁.

协同锁,是用户进程主动申请文件锁,锁才能起作用。比如,A进程已经对文件加了协同锁,如果B进程不去申请锁,而直接对文件进行写操作,也是可以的。

强制锁,是由操作系统内核保证的。不需要用户进程自己去申请。

flock命令使用的就是协同锁。

当一个主进程获取一个文件锁后,fork出的子进程也会获取这个文件锁。

原文链接: crond中使用flock命令的坑,转载请注明来源!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template