我正在尝试创建一个PHP文件,如果它已经在运行,它将无法运行。这是我正在使用的代码:
<?php
class Test {
private $tmpfile;
public function action_run() {
$this->die_if_running();
$this->run();
}
private function die_if_running() {
$this->tmpfile = @fopen('.refresher2.pid', "w");
$locked = @flock($this->tmpfile, LOCK_EX|LOCK_NB);
if (! $locked) {
@fclose($this->tmpfile);
die("Running 2");
}
}
private function run() {
echo "NOT RUNNNING";
sleep(100);
}
}
$test = new Test();
$test->action_run();
问题是,当我从控制台运行它时,它运行良好。但是当我尝试从浏览器运行它时,许多实例可以同时运行。这是在Windows 7,XAMPP,PHP 5.3.2上。我想操作系统认为它是相同的过程,因此功能下降。是否有一种跨平台的方式来创建这种类型的PHP脚本?
答案 0 :(得分:0)
没有什么可以承诺的。你不能像这样使用flock。
您可以使用system()启动另一个(php)进程,为您执行锁定。但缺点是:
另一种方法是启动另一个一直运行的程序。您使用某种IPC连接它(可能只是使用tcp通道,因为它是跨平台的)并允许该程序管理文件访问。该程序也可以是无限循环中的PHP脚本,但用Java或其他支持多线程的语言编写代码可能更简单。
另一种方法是利用现有的资源。为锁创建一个虚拟数据库表,为该文件创建一个条目,然后执行表行锁定。
另一种方法是不使用文件,而是使用数据库。
答案 1 :(得分:0)
前一段时间我遇到过类似的问题。 我需要一个计数器,其中返回的数字是唯一的。 我使用了一个锁文件,只有当这个实例能够创建锁文件时,才允许使用当前编号读取该文件。
也许你可以允许脚本运行,而不是计数。 诀窍是让我们尝试几次(比如5次),中间等待一小段时间。
function GetNextNumber()
{
$lockFile = "lockFile.txt";
$lfh = @fopen($lockFile, "x");
if (!$lfh)
{
$lockOkay = false;
$count = 0;
$countMax = 5;
// Try ones every second in 5 seconds
while (!$lockOkay & $count < $countMax)
{
$lfh = @fopen($lockFile, "x");
if ($lfh)
{
$lockOkay = true;
}
else
{
$count++;
sleep(1);
}
}
}
if ($lfh)
{
$fh = fopen($myFile, 'r+') or die("Too many users. ");
flock($fh, LOCK_EX);
$O_nextNumber = fread($fh, 15);
$O_nextNumber = $O_nextNumber + 1;
rewind($fh);
fwrite($fh, $O_knr);
flock($fh, LOCK_UN);
fclose($fh);
unlink($lockFile); // Sletter lockfilen
}
return $O_nextNumber;
}