【发布时间】:2018-01-11 17:16:44
【问题描述】:
我有一个 index.php 脚本,用作 Google 代码网站上的提交后 URL。此脚本克隆一个目录并构建一个可能需要一些工作的项目。我想避免让这个脚本并行运行不止一次。
如果另一个脚本已经在会话中,我可以使用一种机制来避免执行该脚本吗?
【问题讨论】:
我有一个 index.php 脚本,用作 Google 代码网站上的提交后 URL。此脚本克隆一个目录并构建一个可能需要一些工作的项目。我想避免让这个脚本并行运行不止一次。
如果另一个脚本已经在会话中,我可以使用一种机制来避免执行该脚本吗?
【问题讨论】:
您可以使用flock 和LOCK_EX 来获得文件的排他锁。
例如:
<?php
$fp = fopen('/tmp/php-commit.lock', 'r+');
if (!flock($fp, LOCK_EX | LOCK_NB)) {
exit;
}
// ... do stuff
fclose($fp);
?>
对于 5.3.2 之后的 PHP 版本,您需要使用手动释放锁 羊群($fp, LOCK_UN);
【讨论】:
flock 上的 PHP 手册,LOCK_NB 在那里不起作用。它将在flock 上等待,直到之前的实例完成,然后运行整个代码。
$fp = fopen('/tmp/php-commit.lock', 'c'); 如果 commit.lock 文件不存在,使用 'r+' 会引发 PHP 错误。
运行需要多长时间。
可以使用内存缓存
<?php
$m = new Memcache(); // check the constructor call
if( $m->get( 'job_running' ) ) exit;
else $m->set( 'job_running', true );
//index code here
//at the end of the script
$m->delete( 'job_running' );
?>
如果任务失败,您需要从内存缓存中清除。 Flock 也是一个不错的选择……实际上可能更好。
【讨论】:
仅当您保存正在运行的脚本的状态并检查脚本何时启动时是否有其他脚本当前处于活动状态。
例如,如果脚本正在运行,您可以执行以下操作来保存:
$state = file_get_contents('state.txt');
if (!$state) {
file_put_contents('state.txt', 'RUNNING, started at '.time());
// Do your stuff here...
// When your stuff is finished, empty file
file_put_contents('state.txt', '');
}
【讨论】: