Skip to content

Instantly share code, notes, and snippets.

@sfinktah
Last active September 20, 2023 11:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sfinktah/811df4f9d7e73a024570eb0232f66e7d to your computer and use it in GitHub Desktop.
Save sfinktah/811df4f9d7e73a024570eb0232f66e7d to your computer and use it in GitHub Desktop.
single instance php lock
<?php
namespace Sfinktah\Locks;
class SingleInstanceLock {
private string $lockFile;
private int $pid;
public function __construct($scriptName = null) {
if (!$scriptName) {
$scriptName = $argv[1] ?? 'singleInstanceLock';
}
$this->lockFile = "/tmp/{$scriptName}.pid";
$this->pid = getmypid();
}
public function acquireLock($waitSeconds = 0) {
$startTime = time();
while (file_exists($this->lockFile)) {
$oldPid = (int) file_get_contents($this->lockFile);
if ($this->isProcessRunning($oldPid)) {
if (time() - $startTime >= $waitSeconds) {
return false;
}
sleep(1); // Wait for 1 second before checking again.
} else {
unlink($this->lockFile);
break;
}
}
file_put_contents($this->lockFile, $this->pid);
// Register a shutdown function to release the lock if the script unexpectedly ends.
register_shutdown_function([$this, 'releaseLock']);
return true;
}
public function releaseLock() {
if (file_exists($this->lockFile) && (int) file_get_contents($this->lockFile) === $this->pid) {
unlink($this->lockFile);
}
}
private function isProcessRunning($pid) {
if (empty($pid) || !is_numeric($pid)) {
return false;
}
if (strncasecmp(PHP_OS, 'win', 3) === 0) {
// Windows does not support this method, you can use other methods to check process existence on Windows.
return true; // For demonstration purposes, always assume it's running.
} else {
// On Unix-like systems, check if the /proc directory exists for the given PID.
return file_exists("/proc/{$pid}");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment