I'm attempting to implement a simple non-blocking semaphore in PHP using the built-in shared memory functions. My script essentially looks like this:
$key = ftok(__FILE__, 'A');
$shmId = shm_attach($key);
$runningKey = 37238383940234;
// die now if the script is already running
if (shm_has_var($shmId, $runningKey)) {
echo "Another instance is running
";
exit;
}
// tell other instances that I'm running so that they die
shm_put_var($shmId, $runningKey, true);
sleep(20);
// drop shared memory key
shm_remove_var($shmId, $runningKey);
// terminate script
exit;
This works great as long as the script starts and ends normally. But, suppose the script died unexpectedly while it was running (after shm_put_var(), but before shm_remove_var()). For example, the process is killed by control-C or sent a SIGTERM. My tests have shown that when the script is re-started, the shared memory variable retains the value set by the now-dead instance. I can understand why this might be. However, I'm looking for a workaround, or perhaps some advice on an alternate approach.
My goal is a non-blocking semaphore that will keep multiple instances of the same CLI script from piling up on each other, while at the same time accounting for the case where a script sets the semaphore and dies before it has a chance to clear it.
Much thanks!