exec()超时

Nik*_*kiC 8 php timeout exec

我正在寻找一种方法来运行超时的PHP进程.目前我只是使用exec(),但它没有提供超时选项.

我也尝试过使用proc_open()和使用stream_set_timeout()生成的管道打开过程,但这也不起作用.

那么,有没有办法用超时运行命令(精确的PHP命令)?(PS:这是针对max_execution_time限制失败的情况,因此无需建议.)

(顺便说一下,我还需要检索进程的返回码.)

Dav*_*iev 23

我对这个主题进行了一些搜索并得出结论,在某些情况下(如果你使用的是linux)你可以使用'timeout'命令.它非常灵活

Usage: timeout [OPTION] DURATION COMMAND [ARG]...
  or:  timeout [OPTION]
Run Code Online (Sandbox Code Playgroud)

在我的特殊情况下,我正在尝试从PHP运行sphinx索引器,有点迁移数据脚本所以我需要重新索引我的sphinx文档

exec("timeout {$time} indexer --rotate --all", $output);
Run Code Online (Sandbox Code Playgroud)

然后我将分析输出并决定再尝试一次,或者抛出异常并退出我的脚本.


rom*_*omo 5

我在php.net上发现了这个,我认为可以做你想要的

<?php 
function PsExecute($command, $timeout = 60, $sleep = 2) { 
    // First, execute the process, get the process ID 

    $pid = PsExec($command); 

    if( $pid === false ) 
        return false; 

    $cur = 0; 
    // Second, loop for $timeout seconds checking if process is running 
    while( $cur < $timeout ) { 
        sleep($sleep); 
        $cur += $sleep; 
        // If process is no longer running, return true; 

       echo "\n ---- $cur ------ \n"; 

        if( !PsExists($pid) ) 
            return true; // Process must have exited, success! 
    } 

    // If process is still running after timeout, kill the process and return false 
    PsKill($pid); 
    return false; 
} 

function PsExec($commandJob) { 

    $command = $commandJob.' > /dev/null 2>&1 & echo $!'; 
    exec($command ,$op); 
    $pid = (int)$op[0]; 

    if($pid!="") return $pid; 

    return false; 
} 

function PsExists($pid) { 

    exec("ps ax | grep $pid 2>&1", $output); 

    while( list(,$row) = each($output) ) { 

            $row_array = explode(" ", $row); 
            $check_pid = $row_array[0]; 

            if($pid == $check_pid) { 
                    return true; 
            } 

    } 

    return false; 
} 

function PsKill($pid) { 
    exec("kill -9 $pid", $output); 
} 
?>
Run Code Online (Sandbox Code Playgroud)


Flo*_*ian 2

您可以在一个进程中fork()然后在另一个进程中非阻塞。如果未及时完成,还要跟踪超时和其他进程。exec()wait()kill()