Check if a PHP script is already running
Posted October 28th, 2008 in PHP (Updated October 29th, 2008)
If you have long running batch processes with PHP that are run by cron and you want to ensure there's only ever one running copy of the script, you can use the functions getmypid() and posix_kill() to check to see if you already have a copy of the process running. This post has a PHP class for checking if the script is already running.
Each process running on a Linux/Unix computer has a pid, or process identifier. In PHP this can be retrieved using getmypid() which will return an integer number. This pid number can be saved to a file and each time the script is run a check made to see if the file exists. If it is the posix_kill() function can be used to see if a process is running with that pid number.
My PHP class for doing this is below. Please feel free to use this and modify to suit your individual requirements.
class pid {
protected $filename;
public $already_running = false;
function __construct($directory) {
$this->filename = $directory . '/' . basename($_SERVER['PHP_SELF']) . '.pid';
if(is_writable($this->filename) || is_writable($directory)) {
if(file_exists($this->filename)) {
$pid = (int)trim(file_get_contents($this->filename));
if(posix_kill($pid, 0)) {
$this->already_running = true;
}
}
}
else {
die("Cannot write to pid file '$this->filename'. Program execution halted.\n");
}
if(!$this->already_running) {
$pid = getmypid();
file_put_contents($this->filename, $pid);
}
}
public function __destruct() {
if(!$this->already_running && file_exists($this->filename) && is_writeable($this->filename)) {
unlink($this->filename);
}
}
}
and it can be used as follows:
$pid = new pid('/tmp');
if($pid->already_running) {
echo "Already running.\n";
exit;
}
else {
echo "Running...\n";
}
To test it, you could add "sleep(30);" to the end of the test script above, run the script and then run the script again. The second time you run it the script will output "Already running" and exit.
The class tidies up the pid file at the end of the script run automatically in the desctructor, so all you need to do is create the object at the start and then check to see if it's already running.
Update 29 Oct 2008: I forgot to mention when I wrote this yesterday that posix_kill() will return true if there is already a process running with $pid which is being run by the same user your script is running as. Pid numbers do get recycled when the limit is reached, so it is potentially possible (although unlikely) that you might be checking another process that was run by you and not the same exact PHP script. If you run the script as root querying any pid that is actually running will return true.
Related posts:
- PHP CLI counter for long running processes (Friday, August 29th 2008)
- List compiled modules with the PHP CLI (Sunday, June 29th 2008)
- Command line arguments for the PHP CLI (Thursday, June 19th 2008)
- Command line arguments with a PHP CLI script (Sunday, June 15th 2008)
- Determine whether PHP is being run via HTTP or CLI - Follow Up (Sunday, March 9th 2008)
- Determine whether PHP is being run via HTTP or CLI (Saturday, March 8th 2008)
Recent posts:
- MySQL queries for article summaries part 2 of 2 (Tuesday, January 6th 2009)
- Aims for 2009 (Monday, January 5th 2009)
- Weekly Roundup - January 5th 2008 (Monday, January 5th 2009)
- MySQL queries for article summaries part 1 of 2 (Sunday, January 4th 2009)
- 2008 Summary of Posts (Saturday, January 3rd 2009)
- 2008 / 2009 overview (Friday, January 2nd 2009)
Subscribe to RSS Feed / Email / Bookmark / Share
Use the buttons below to subscribe to my RSS feed to be notified next time something is posted, share this post with others, or subscribe by email and have my posts sent in a daily email.
Posts are made using the following schedule (although it may vary some weeks): Mondays & Fridays = PHP; Tuesdays & Saturdays = MySQL; Wednesdays & Sundays = Javascript/jQuery; Thursdays = HTML/CSS.
