Home > Article > Backend Development > PHP process synchronization code example, php process example_PHP tutorial
We often encounter a situation where a scheduled task executes a certain PHP program in the background at a scheduled time. Sometimes it also needs to be executed manually. Multiple people may need to execute this program. If the task duration is very long, it is easy to cause repeated execution. , so the following class was developed.
Function: Before running the actual code, check whether the process with the same operation as the current one is running. High-concurrency operation is reliable, and abnormal interruption of the running process will not have any impact.
The construction method passes the absolute path of the pid file directory, and you need to ensure that different processes correspond to different pid files.
/*
* The same PHP process only runs once. Based on the process name, it is judged whether it is a deduplication process. It can only run on Linux. It is concurrency-safe under high concurrency conditions.
*/
class SyncProcess {
private $pidFile;
function __construct($pidFile) {
$this->pidFile = $pidFile;
}
/**
* Non-blocking mode returns whether the process is running
*/
function check() {
if (PHP_OS == 'Linux') {
$pidFile = $this->pidFile;
if (!empty($pidFile)) {
$flag = false;
$pidDir = dirname($pidFile);
If (is_dir($pidDir)) {
$flag = true;
}
If ($flag) {
$running = true;
clearstatcache(true, $this->pidFile);
If (!file_exists($this->pidFile))
file_put_contents($this->pidFile, '', LOCK_EX);
$f = fopen($this->pidFile, 'r+');
If (flock($f, LOCK_EX ^ LOCK_NB)) {
$pid = trim(fgets($f));
If (!$this->is_process_running($pid)) {
$running = false;
}
}
If (!$running) {
fseek($f, 0);
ftruncate($f, 0);
fwrite($f, getmypid());
}
flock($f, LOCK_UN);
fclose($f);
Return $running;
} else {
debug_print("pid file($pidFile) is invalid", E_USER_WARNING);
}
} else {
debug_print("pid file cant't be empty", E_USER_WARNING);
}
} else {
debug_print(__CLASS__ . ' can only run in Linux', E_USER_WARNING);
Return true;
}
}
/**
* Returns true if it is running or an unknown error occurs, false if it is not running
* @param mixed $pid
*/
private function is_process_running($pid) {
if (is_numeric($pid) && $pid > 0) {
$output = array();
$line = exec("ps -o pid --no-headers -p $pid", $output);
//The return value has spaces
$line = trim($line);
if ($line == $pid) {
Return true;
} else {
If (empty($output)) {
Return false;
} else {
If (php_sapi_name() == 'cli')
$n = "n";
else
$n = "
";
//If we get to this point, something must have gone wrong
$output = implode($n, $output);
debug_print($output, E_USER_WARNING);
Return true;
}
}
}else {
Return false;
}
}
}
Demo: