crond中使用flock命令的坑

php中文网
发布: 2016-06-23 09:09:34
原创
1208人浏览过

现象

需要定期去执行一个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'
登录后复制

脚本只会在第一次成功执行,之后就不会再执行。当删除/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
登录后复制

发现脚本可以正常执行了。那必定是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"));?>
登录后复制

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

Git版本控制与工作流 中文WORD版
Git版本控制与工作流 中文WORD版

篇文章是针对git版本控制和工作流的总结,如果有些朋友之前还没使用过git,对git的基本概念和命令不是很熟悉,可以从以下基本教程入手: Git是分布式版本控制系统,与SVN类似的集中化版本控制系统相比,集中化版本控制系统虽然能够令多个团队成员一起协作开发,但有时如果中央服务器宕机的话,谁也无法在宕机期间提交更新和协同开发。甚至有时,中央服务器磁盘故障,恰巧又没有做备份或备份没及时,那就可能有丢失数据的风险。感兴趣的朋友可以过来看看

Git版本控制与工作流 中文WORD版 0
查看详情 Git版本控制与工作流 中文WORD版
[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
登录后复制

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

解决方法

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

延伸阅读

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

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

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

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

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

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

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号