[ACCEPTED]-PHP Check Process ID-process
In linux, you would look at /proc.
return file_exists( "/proc/$pid" );
In Windows 11 you could shell_exec() tasklist.exe, and 10 that would find a matching process id:
$processes = explode( "\n", shell_exec( "tasklist.exe" ));
foreach( $processes as $process )
{
if( strpos( "Image Name", $process ) === 0
|| strpos( "===", $process ) === 0 )
continue;
$matches = false;
preg_match( "/(.*?)\s+(\d+).*$/", $process, $matches );
$pid = $matches[ 2 ];
}
I 9 believe what you want to do is maintain 8 a PID file. In the daemons I've written, they 7 check a config file, look for an instance 6 of a pid file, get the pid out of the pid 5 file, check to see if /proc/$pid exists, and 4 if not, delete the pid file.
if( file_exists("/tmp/daemon.pid"))
{
$pid = file_get_contents( "/tmp/daemon.pid" );
if( file_exists( "/proc/$pid" ))
{
error_log( "found a running instance, exiting.");
exit(1);
}
else
{
error_log( "previous process exited without cleaning pidfile, removing" );
unlink( "/tmp/daemon.pid" );
}
}
$h = fopen("/tmp/daemon.pid", 'w');
if( $h ) fwrite( $h, getmypid() );
fclose( $h );
Process IDs 3 are granted by the OS and one cannot reserve 2 a process id. You would write your daemon 1 to respect the pid file.
A better way to accomplish this would be 6 to use a pid or a lock file. Simply check 5 for the existence of the pid file, create 4 it as necessary, and populate it with your 3 running pid.
<?
class pidfile {
private $_file;
private $_running;
public function __construct($dir, $name) {
$this->_file = "$dir/$name.pid";
if (file_exists($this->_file)) {
$pid = trim(file_get_contents($this->_file));
if (posix_kill($pid, 0)) {
$this->_running = true;
}
}
if (! $this->_running) {
$pid = getmypid();
file_put_contents($this->_file, $pid);
}
}
public function __destruct() {
if ((! $this->_running) && file_exists($this->_file)) {
unlink($this->_file);
}
}
public function is_already_running() {
return $this->_running;
}
}
?>
And use it as follows:
<?
$pidfile = new pidfile('/tmp', 'myscript');
if($pidfile->is_already_running()) {
echo "Already running.\n";
exit;
} else {
echo "Started...\n";
}
?>
There's 2 not much error checking here, but a quick 1 run shows this works on my system.
For checking if a PID exist on a windows 15 machine i use:
function pidExists($pid)
{
exec('TASKLIST /NH /FO "CSV" /FI "PID eq '.$pid.'"', $outputA );
$outputB = explode( '","', $outputA[0] );
return isset($outputB[1])?true:false;
}
Note that $outputB[0] contains a messages 14 that pid can't be found, if the pid indeed 13 doesn't exists! So to validate i use the 12 second argument.
EDIT:
To expand on this, its 11 also possible to dynamically spawn scripts 10 within windows in the background using powershell 9 like so:
// this function builds an argument list to parse into the newly spawned script.
// which can be accessed through the superglobal global $argv;
function buildArgList( array $arguments){
return ' '. implode(' ', $arguments) .' ';
}
$arguments = buildArgList(['argument1','argument2','argument3']);
$windowstyle = 'normal'; // or you can use hidden to hide the CLI
pclose(popen("powershell start-process -FilePath '" . PHP_BINARY . "' -ArgumentList '-f\"" . $file . " " . $arguments . "\"' -WindowStyle " . $windowstyle,"r"));
The script you spawn can then use: cli_set_process_title to 8 set that process's title to some unique 7 hash.
within the parent that spawned the 6 child process you can use the following 5 code to find that process within the tasklist 4 using its windowtitle searching for the 3 uniquehash.
exec('TASKLIST /NH /FO "CSV" /FI "windowtitle eq ' . escapeshellarg($uniquehash) . '"', $output );
When combined with a database 2 you can essentially build a workermanager communicating 1 between different php scripts.
No you cannot change any processes pid. It 2 is assigned by the kernel and is part of 1 the kernel's data structures
As others have said, you cannot change the 22 process id - it is assigned and entirely 21 manged by the kernel of the OS. Additionally, you 20 have not said if this is command-line or 19 web-server based: if it's the latter you 18 may not even be getting the pid of your 17 script.
The manual page for getmypid() contains some examples of "optimistic" locking. I 16 use the word optimisitc as PHP is never 15 ever going to approach the likes of an asp.net 14 web application where you have a true threaded 13 environment with shared/static classes and 12 thus Singleton's to use/abuse. Basically 11 you have the option of:
- Touching a "lock file" on the file-system somewhere. Your script then checks if that file exists: if it does, terminate, otherwise, touch that file and carry on processing
- Setting a database based flag to say the script is running. As above, but use a db table/field to mark a script as running.
Both of these rely 10 on the script terminating correctly (as 9 the last step would be to remove the lock 8 file/db flag). If a script crashes for 7 any reason (or the machine itself), you 6 can be left with a manual tidy-up process 5 to remove the flag. There is no easy solution 4 for this, but one avenue to explore would 3 be to then look at date-stamping the lock, with 2 an arbitary "if older than X, the last 1 run must have crashed" approach.
Don't forget also that you can access shell 3 commands via backticks (`), which would 2 give you access to the standard *nix tools 1 for working with pids.
source: http://www.php.net/manual/en/language.operators.execution.php
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.