简体   繁体   English

PHP进程ID和唯一

[英]PHP Process ID and unique

I want to run a php script on background and store its PID on database. 我想在后台运行php脚本并将其PID存储在数据库中。 So that I can check if the particular script running or not (later). 这样我就可以检查特定脚本是否正在运行(稍后)。

We can use getmypid to get current PID. 我们可以使用getmypid来获取当前的PID。

But as per the PHP manual 但是根据PHP手册

Process IDs are not unique, thus they are a weak entropy source. 进程ID不是唯一的,因此它们是弱熵源。 We recommend against relying on pids in security-dependent contexts. 我们建议不要依赖于依赖于安全性的上下文中的pids。

...and I cannot rely on PID. ......我不能依赖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? 以后如何与tasklist进行比较以检查特定脚本是否正在运行?

I am running on a shared host, windows/linux environment. 我在共享主机,Windows / Linux环境中运行。

From php.net/getmypid 来自php.net/getmypid

with little modification to disable non cli access. 几乎没有修改来禁用非cli访问。

script can be executed using /usr/bin/php script.php . 脚本可以使用/usr/bin/php script.php

Additionally use nohup /usr/bin/php script.php > nohup.out & to launch a nohup process in background. 另外使用nohup /usr/bin/php script.php > nohup.out &在后台启动nohup进程。

#!/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. 您可以使用PHP CLI,存储PID(它们在特定时间点是唯一的,因此您不会有2个运行相同PID的进程)并在ps -ax的输出中grep它们以检查它们是否正在运行。 If not - delete them from database, so that you won't have problem with the same PID occuring. 如果不是 - 从数据库中删除它们,这样你就不会遇到同样的PID问题。

You can try use the PID with another id, for example: 您可以尝试将PID与另一个id一起使用,例如:

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. 如果您有一个使用文件ID = 327的压缩作业,请尝试存储{PID} 327,并检查此特定作业是否仍在运行。

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. 即使PID被重用,你也不会存储id为327的PID,或者如果你用这个特殊的id 327重新启动压缩过程,可能会改变PID。

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. 但是,为了避免使用此id 327获取相同的PID,您必须先检查数据库,然后在组合ID的末尾添加一个计数器,如{PID} 327_1。

Hope this can help you. 希望这可以帮到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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