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 を 2 回開くと、常に「ジョブが完了しました」と表示されます。おそらく、同じプロセスと見なされるためでしょうか? それを行う方法はありますか?同様の結果で getmypid() も試しました。

ありがとう

4

3 に答える 3

2

私のために働きます。

スクリプトがディレクトリにファイルを作成できることを確認してください。「unlink」行のコメントを外してスクリプトを実行し、ディレクトリにロック ファイルが存在するかどうかを確認します。表示されない場合は、ディレクトリのアクセス許可の問題です。

于 2010-04-26T16:15:30.063 に答える
2

私にとっては機能するため、「通常の簡単な」環境を想定した特定のケースの何が問題なのかはわかりませんが、少なくともコードに競合状態があります。2 つのプロセスをまったく同時に開始し、両方のプロセスでdemo.lockが存在しないことが判明した場合はどうなるでしょうか。

モードで使用fopenして、xこれが起こらないようにすることができます。X モードはファイルを作成しようとします。すでに存在する場合は失敗し、E_WARNINGエラーが生成されます (したがって、shutup オペレーター)。ファイルシステム操作はドライブ上でアトミックであるため、一度に 1 つのプロセスだけがファイルを保持できることが保証されます。

<?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 に答える