Often encountered in such a situation, scheduled tasks in the background to execute a PHP program, and sometimes need to manually execute, may be many individuals need to execute this program, if the task lasts a very long time, it is easy to repeat execution, so developed the following class.
Role: Check that the process is running before the actual code is running, that high concurrency is reliable, and that an abnormal interrupt in the middle of a running process will have no effect.
The construction method passes the absolute path of the PID file directory, and needs to guarantee different PID files for different processes.
Copy Code code as follows:
<?php
/*
* The same PHP process only run once, according to the process name to determine whether the process of weight, can only run on Linux, high concurrency conditions are concurrent security.
*/
Class Syncprocess {
Private $pidFile;
function __construct ($pidFile) {
$this->pidfile = $pidFile;
}
/**
* Non-blocking 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 an unknown error is running or if it is not running returns false
* @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 a space
$line = Trim ($line);
if ($line = = $pid) {
return true;
} else {
if (empty ($output)) {
return false;
} else {
if (php_sapi_name () = = ' CLI ')
$n = "\ n";
Else
$n = "<br>";
It's going to be a problem at this stage.
$output = Implode ($n, $output);
Debug_print ($output, e_user_warning);
return true;
}
}
}else {
return false;
}
}
}
Demo:
Copy Code code as follows:
$sync = new Syncprocess (App_path. '/data/pid '. Implode (", $this->getroute ()));
if ($sync->check ()) {
Exit ("process is running\n");
}