PHP Exec возвращает неверный идентификатор процесса - PullRequest
1 голос
/ 28 декабря 2011

Я использую PHP для запуска команды транскодирования FFMPEG.Это типичная установка LAMP, работающая на сервере Ubuntu 10.04, в конфигурации нет ничего особенного.

Проблема, с которой я сталкиваюсь, заключается в том, что когда я запускаю команду PHP Exec, она возвращает неверный идентификатор процесса.Вместо того, чтобы возвращать правильный PID, он возвращает тот, который на 2 выше.то есть идентификатор процесса FFMPEG будет 3557, но PHP Exec возвращает 3559.

Мне постоянно удавалось производить это каждый раз.Проблема в том, что мне действительно нужен правильный идентификатор процесса, чтобы я мог остановить процесс позже, если я решу.

Команда FFMPEG работает и запускается без проблем, поэтому я не думаю, что она является источникомпроблема:

$cmd = "ffmpeg -r 4 -f mjpeg -an -i 'http://" . $internalhost . ":" . $stream_port . "'
-vcodec libx264 -vpre fastfirstpass -vpre baseline -b 24k -bt 32k -threads 0 
http://localhost:8090/" . $localport . ".ffm";
$ffmpg = new Process($cmd);

Я знаю ... это довольно уродливо, но это работает, и я не думаю, что переменные важны.

Для запуска кода я использую класс изсайт PHP Manual, который выглядит следующим образом:

class Process
{
private $pid;
private $command;

public function __construct($cl=false){
    if ($cl != false){
        $this->command = $cl;
        $this->runCom();
    }
}
private function runCom(){
    $command = 'nohup '.$this->command.' > /dev/null 2> /dev/null & echo $!';
    exec($command ,$op);
    $this->pid = (int)$op[0];
}

public function setPid($pid){
    $this->pid = $pid;
}

public function getPid(){
    return $this->pid;
}

public function status(){
    $command = 'ps -p '.$this->pid;
    exec($command,$op);
    if (!isset($op[1]))return false;
    else return true;
}

public function start(){
    if ($this->command != '')$this->runCom();
    else return true;
}
public function stop(){
    $command = 'kill '.$this->pid;
    exec($command);
    if ($this->status() == false)return true;
    else return false;
}
}

Я думаю, что происходит то, что по какой-то причине FFMPEG запускает еще 2 процесса и вместо того, чтобы возвращать PID для основного процесса, он возвращаетPID для последнего процесса.

Возможно, это неправильно, но я все еще чешу голову.

1 Ответ

0 голосов
/ 04 февраля 2013

Идентификатор процесса берется из echo $!, и руководство Bash утверждает, что $! «Расширяет до идентификатора процесса самой последней выполненной фоновой (асинхронной) команды». У меня было бы такое же предчувствие, как и у вас, что FFMPEG порождает дополнительные процессы, по крайней мере, один из которых находится в фоновом режиме, и, следовательно, $! запускает его. Не могли бы вы запустить дополнительные тесты, чтобы проверить это? Во-первых, вместо 'ffmpeg' запустите что-то долгоживущее как $cmd, которое, как вы знаете, не вызовет фоновых процессов, такое как md5sum /dev/zero, и посмотрите, соответствует ли идентификатор процесса, который вы получаете из getPid(), тому, что вы видите в ps. Во-вторых, когда вы запускаете исходный код, то, что, по словам ps X (в командной строке), выполняется, где X - это число, сообщаемое getPid()? Означает ли выполнение ps fwax | grep -3 X (опять же, замена X), что X является дочерним процессом процесса с идентификатором X - 2?

Если этот процесс действительно является фоновым процессом, порожденным 'ffmpeg', пытались ли вы его убить? Этого также может быть достаточно для уничтожения родительского процесса.

...