简体   繁体   中英

PHP Process ID and unique

I want to run a php script on background and store its PID on database. So that I can check if the particular script running or not (later).

We can use getmypid to get current PID.

But as per the PHP manual

Process IDs are not unique, thus they are a weak entropy source. We recommend against relying on pids in security-dependent contexts.

...and I cannot rely on PID.

My second idea is to store the process created time to the database.

How can I get the current script created time? And later how can I compare with tasklist to check whether the particular script is running or not?

I am running on a shared host, windows/linux environment.

From php.net/getmypid

with little modification to disable non cli access.

script can be executed using /usr/bin/php script.php .

Additionally use nohup /usr/bin/php script.php > nohup.out & to launch a nohup process in background.

#!/usr/bin/php 
<?php 

if ( PHP_SAPI !== 'cli' ) {
    die( "Cmd line access only!\n" );
}

define( 'LOCK_FILE', "/var/run/".basename( $argv[0], ".php" ).".lock" );  // can also use /tmp
if( isLocked() ) die( "Already running.\n" ); 

# The rest of your script goes here.... 
echo "Hello world!\n"; 
sleep(30); 

unlink( LOCK_FILE ); 
exit(0); 

function isLocked() 
{ 
    # If lock file exists, check if stale.  If exists and is not stale, return TRUE 
    # Else, create lock file and return FALSE. 

    if( file_exists( LOCK_FILE ) ) 
    { 
        # check if it's stale 
        $lockingPID = trim( file_get_contents( LOCK_FILE ) ); 

       # Get all active PIDs. 
        $pids = explode( "\n", trim( `ps -e | awk '{print $1}'` ) ); 

        # If PID is still active, return true 
        if( in_array( $lockingPID, $pids ) )  return true; 

        # Lock-file is stale, so kill it.  Then move on to re-creating it. 
        echo "Removing stale lock file.\n"; 
        unlink( LOCK_FILE ); 
    } 

    file_put_contents( LOCK_FILE, getmypid() . "\n" ); 
    return false; 

} 
?>

It all depends on your level of access to target machine. You can use PHP CLI, store PIDs (they are unique to particular point in time, so you won't have 2 processes with same PIDs running) and grep them in the output of ps -ax to check if they are running. If not - delete them from database, so that you won't have problem with the same PID occuring.

You can try use the PID with another id, for example:

if you have a zipping job that uses a file id = 327, try to store {PID}327, and with this check if this particular job still running.

Even if the PID get reused, you will not have that PID with id 327 stored, or if you restart the zipping process with this particular id 327, probabily the PID will change.

But, to avoid get the same PID with this id 327, you'll have to check your database before, and then add a counter at the end of the composed id, like {PID}327_1.

Hope this can help you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM