When running php via cron, there are certainly situations where you only want a single instance of the php file to be running at the same time. Multiple processes shouldn’t be allowed. For example, every 5 minutes, a process is launched to poll for weather updates, and publish them to Twitter. If, for some reason, this process takes more than 15m–because Twitter is very slow–I don’t want more to buildup. At a rate of 12/hr, I would exhaust the number of MySQL connection on my box in a couple hours.
So, here’s the solution I used:
<?php class pid { protected $filename; protected $fp; public $already_running = false; function __construct() { $this->filename = dirname(__FILE__).'/'.basename($_SERVER['PHP_SELF']) . '.pid'; $this->fp = fopen( $this->filename, 'w+ ); if ( !flock( $this->fp, LOCK_EX + LOCK_NB ) ) { echo "FAILED lock $this->filename\n"; $this->already_running = true; fclose($this->fp); } else { echo "Acquired lock $this->filename\n"; } } public function __destruct() { if( !$this->already_running ) { echo "Releasing lock $this->filename\n"; flock($this->fp, LOCK_UN); fclose($this->fp); } } } ?>
It works fine from command line, but for some reason, doesn’t work when invoked via Apache over the web. But since I’m just using it for cron jobs, this is good enough for now. If you know why FLOCK( LOCK_EX + LOCK_NB ) won’t work when invoked through Apache, let me know!! I’m running PHP 5.2.6 (cli) and Apache/2.2.9 (Unix).