6

我正在尝试使用临时文件 demo.lock 检查进程是否已在运行:

演示.php:

<?php
    $active=file_exists('demo.lock');
    if ($active)
    {
        echo 'process already running';
    }
    else
    {
        file_put_contents ('demo.lock', 'demo');
        sleep(10);  //do some job
        unlink ('demo.lock');
        echo 'job done';
    }
?>

但是它似乎不起作用:如果我打开 demo.php 两次它总是显示“工作完成”,也许是因为它认为它是相同的过程?有什么办法吗?我也尝试使用 getmypid() 获得类似的结果。

谢谢

4

3 回答 3

2

为我工作。

确保脚本可以在目录中创建文件。取消注释“unlink”行并运行脚本并检查目录中是否存在锁定文件。如果您没有看到它,那么这是一个目录权限问题。

于 2010-04-26T16:15:30.063 回答
2

假设“正常,简单”的环境,无法确定您的具体情况有什么问题,因为它对我有用,但至少您的代码中有竞争条件。如果您同时启动两个进程,并且都发现demo.lock不存在怎么办?

您可以使用fopenwithx模式来防止这种情况发生。X模式尝试创建文件;如果它已经存在,它会失败并产生一个E_WARNING错误(因此是闭嘴操作员)。由于文件系统操作在驱动器上是原子操作,因此可以保证一次只有一个进程可以保存文件。

<?php

$file = @fopen("demo.lock", "x");
if($file === false)
{
    echo "Unable to acquire lock; either this process is already running, or permissions are insufficient to create the required file\n";
    exit;
}

fclose($file); // the fopen call created the file already
sleep(10); // do some job
unlink("demo.lock");
echo "Job's done!\n";

?>

我在这里测试过,它似乎工作。

于 2010-04-26T16:15:36.467 回答
0

好吧,发送一些标题和刷新似乎对我有用(不知道为什么),所以现在当我加载页面时显示“开始”并且如果我在完成该过程之前点击浏览器上的刷新按钮,警告消息:

<?php

$file = @fopen("demo.lock", "x");
if($file === false)
{
    echo "Unable to acquire lock; either this process is already running, or permissions are insufficient to create the required file\n";
    exit;
}

header("HTTP/1.0 200 OK");
ob_start();
echo "Starting";
header('Content-Length: '.ob_get_length(),true);
ob_end_flush();
flush();

fclose($file); // the fopen call created the file already
sleep(10); // do some job
unlink("demo.lock");    
?>

感谢到目前为止所有的答案和建议

于 2010-04-28T10:05:09.170 回答