LINUX.ORG.RU

Вопрос по дочерним процессам

 ,


0

1

Здрасти всем!

Написал скрипт php, который запускает 2 процесса через proc_open()
Мне нужно определить PID дочерних процессов(B и C). Казалось бы простая задача

$info = proc_get_status($process);
$info['pid']

Но возвращает пид 24326, а не 24334, потому что запускается какая то прокладка sh. Для чего она нужна и зачем запускается - вопрос?

Я записал небольшую ф-ию, которая через команду pgrep -P pid, определяет самого последнего потомка, но бывает иногда что она его не видит и определяет пид sh(вместо B). Возможно ли, что после proc_open() успевает запуститься только sh, а скрипт B не успевает?

php(24311)─┬─sh(24326)───(B)ffmpeg(24334)
          └─sh(24327)───(C)php(24327)

★★★★

Но возвращает пид 24326, а не 24334, потому что запускается какая то прокладка sh. Для чего она нужна и зачем запускается - вопрос?

А что ты запускаешь? Если какой-то скрипт, то ясен ёжик, что он через интерпретатор будет запущен.

Возможно ли, что после proc_open() успевает запуститься только sh, а скрипт B не успевает?

Конечно, возможно. Сначала интерпретатор инициализируется, а потом уже выполняет скрипт.

tiandrey ★★★★★
()
Ответ на: комментарий от tiandrey

Я запускаю бинарь, ffmpeg, там нет интерпритатора

gobot ★★★★
() автор топика

Первый комментарий (Mark Seecof) отсюда похоже как раз описывает решение твоей проблемы:

On Unix/Linux, if you change the command line you pass to proc_open() just slightly then proc_get_status() will give you the actual process-id (pid) of your child.

Suppose you wish to run the external command /usr/bin/compress to create a BSD foo.Z file. Rather than proc_open(«/usr/bin/compress /tmp/foo»,...) you may invoke proc_open(«exec /usr/bin/compress /tmp/foo»,...) and then proc_get_status()['pid'] will be the actual pid of /usr/bin/compress.

Why? Because the way proc_open() actually works on Unix/Linux is by starting «/bin/sh -c usercmd userargs...», e.g., «/bin/sh -c /usr/bin/compress /tmp/foo».[Note 1] That means normally your command is the child of the shell, so the pid you retrieve with proc_get_status() is the pid of the shell (PHP's child), and you have to fumble around trying to find the pid of your command (PHP's grandchild). But if you put «exec» in front of your command, you tell the shell to *replace itself* with your command without starting another process (technically, to exec your command without forking first). That means your command will inherit the pid of the shell, which is the pid that proc_get_status() returns.

So if you would like the actual pid of the process running your command, just prepend «exec » to your proc_open() command argument then retrieve the pid using proc_get_status().

This also makes proc_terminate() and proc_close() work more like you might prefer, since they will affect the actual process running your command (which will be a child process rather than a grandchild process).

[Note 1] My guess is that the PHP developers want the shell to expand wildcards in path/filenames.

ProtoH
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.