Borgtex
Borgtex

Reputation: 3245

Checking if a php process is already running

I'm trying to check if a process is already running by using a temporal file demo.lock:

demo.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';
    }
?>

however it doesn't seem to work: if I open demo.php twice it always shows "job done", maybe because it considers it the same process? is there some way to do it? I also tried with getmypid() with similar results.

Thanks

Upvotes: 6

Views: 2680

Answers (3)

Borgtex
Borgtex

Reputation: 3245

Well, sending some headers and flushing seems to work for me (not sure why), so now when I load the page shows "Start" and if I hit the refresh button on the browser before completing the process, the warning message:

<?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");    
?>

Thanks for all the answers and suggestions so far

Upvotes: -1

zneak
zneak

Reputation: 138031

Can't be sure about what's wrong with your specific case assuming a "normal, easy" environment because it works for me, but at least you have a race condition in your code. What if you start two processes at the exact same time, and that both find that demo.lock does not exist?

You can use fopen with the x mode to prevent this from happening. The X mode tries to create the file; if it already exists, it fails and generates an E_WARNING error (hence the shut-up operator). Since filesystem operations are atomic on a drive, it is guaranteed that only one process at a time can hold the file.

<?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";

?>

I've tested it here and it seems to work.

Upvotes: 1

zaf
zaf

Reputation: 23244

Works for me.

Make sure the script can create a file in the directory. Uncomment the "unlink" line and run the script and check if the lock file exists in the directory. If you don't see it then it's a directory permissions issue.

Upvotes: 2

Related Questions