Получите возвращаемое значение процесса PID

То, что Вы описываете, является скалистой вершиной middlebox. Кажется, уже существует документация относительно того, как сделать это.

http://www.howtoforge.com/how-to-set-up-a-tor-middlebox-routing-all-virtualbox-virtual-machine-traffic-over-the-tor-network

Это могло бы отличаться, в зависимости от какого администратора сети Вы используете.

2
22.08.2013, 11:28
5 ответов

Это почти наверняка определяется (значение по умолчанию) php.ini или эквивалентная установка:

max_execution_time = 30

TLDR: если Вы уверены, что PHP действительно выходит сначала, и что-то уничтожает Ваш сценарий, то можно или использовать демона, чтобы перенести и контролировать процесс Python (в неперезапуске режима, т.е. без --respawn), или добавьте сигнал handers к сценарию Python.

В целом, если Вы можете выполнить оболочку как идентификатор пользователя сценария, затем необходимо смочь strace или truss процесс, например, на Linux можно сделать это обоснованно эффективно:

 $ sleep 60 &
 [1] 10873
 $ strace -e trace=signal,process  -p $!
 Process 10873 attached - interrupt to quit
 +++ killed by SIGKILL +++
 Process 10873 detached

sleep процесс был завершен с a kill -9 от другого терминала. kill -9 не было бы распространено, хотя, так как процесс не сможет захватить это и чисто выйти.

Контролировать с daemon используйте вариацию на:

daemon -i --errlog=/tmp/mypy.log -- /usr/bin/python [...]

Это зарегистрирует любое связанное с сигналом завершение. Добавить --dbglog и --debug=2 если Вы хотите зарегистрировать каждый выход независимо.

Как отмечено в другом месте, если процесс уже завершился, он пошел. Только родитель (или init) смог бы получить свой код выхода, и если он не был зарегистрирован (возможно использующий учет процесса или аудит), код выхода потерян.

Внутренне для обработки тайм-аута на *отклоняют платформы, PHP настраивает a SIGALARM или SIGPROF с указанным тайм-аутом. Тот обработчик сигналов просто называет внутреннее zend_error() функция. Это действительно однако также называет любые зарегистрированные обратные вызовы и обработчики ошибок, которые могут быть полезны для Вас.

Если обработчик ошибок по умолчанию умрет, то код выхода PHP будет, я верю, 255, так как тайм-аут E_ERROR.

Также отметьте, конвенция кода выхода как 128+N, где N является числом сигнала, происходит из-за поведения определенных оболочек (включая bash) и много API. Фактический код выхода процесса после сигнала системно-зависим. Это - вероятно, просто число сигнала, это обычно имеет место на Linux. wait() группа системных вызовов предоставляет лучше подробную информацию выхода процесса. PHP следует конвенции оболочки, например, если Вы используете popen() и pclose() Вы будете видеть 128+N как код выхода, когда сигнал завершил процесс.

Другое соображение здесь является поведением ограничений по времени PHP, если Вы проверяете set_time_limit() документация Вы будете видеть

set_time_limit () функционируют и конфигурационная директива max_execution_time только влияйте на время выполнения самого сценария. Любое время потратило на действие, которое происходит вне выполнения сценария, такого как использование системных вызовов system(), операции с потоками, запросы базы данных, и т.д. не включены при определении максимального времени, когда сценарий работал. Это не верно в Windows, где измеренное время реально.

Можно доказать это с коротким сценарием:

<?php
# for (;;);
$exe="sleep 20";
print "exit code: " . pclose(popen($exe, 'r'));
?>

Вызовите с time php -d max_execution_time=5 -f sleep3.php. Сценарий будет работать в течение 20 секунд, не будет никакой ошибки. Если Вы уничтожаете спящий процесс, например. kill -USR1 $(pgrep sleep) в другом терминале Вы будете видеть код выхода 138 (128+SIGUSR1).

Если Вы не комментируете большое количество for(;;) цикл, сценарий завершится после 5 секунд.

2
27.01.2020, 21:53
  • 1
    О состоянии сообщают родительскому процессу (через wait семейство системных вызовов), кодирует 8-разрядное значение, переданное _exit если процесс обычно выходил, число сигнала, если процесс был уничтожен сигналом и еще несколькими флагами. Я не знаю, как PHP сообщает об этом, но обычно это не было бы “просто число сигнала”, это будет смещенное на бит число сигнала и с другим набором битов. –  Gilles 'SO- stop being evil' 23.08.2013, 10:26

Процесс, который больше не был уничтожен, существует в системе. На самом деле, на занятом хосте, существует довольно хороший шанс, что продолжительному и начиная с уничтоженного процесса снова использовал его PID некоторый другой процесс, таким образом, Вы закончили бы тем, что смотрели на что-то полностью несвязанное!

Когда процесс уничтожается, он ничего не возвращает. Это просто прекращает существование. Это в отличие от catchable сигнала те, которые ПОНУКАЮТ или USR1, который может процесс (но делает не обязательно) выгода и обрабатывает всегда, это считает целесообразным (включая выход с определенным кодом выхода).

Если у Вас есть достаточный доступ, Вы смогли устанавливать своего рода библиотеку или модуль ядра, который прерывает и записывает syscalls, которые в конечном счете приводят к процессу рассматриваемое получение сигнала, но это действительно кажется легче тому, поскольку pjc50 предложенный просто добавляют сценарий обертки и записывают статус выхода где-нибудь.

Альтернатива не должна была бы заставлять пользователя ожидать, а скорее переместиться в асинхронную архитектуру для того, что Вы делаете, который занимает много времени для завершения.

2
27.01.2020, 21:53
  • 1
    , “Когда процесс уничтожается, он ничего не возвращает”. Верный, но не важный. Когда процесс уничтожается, о числе сигнала сообщают по тому же каналу, который сообщает о статусе выхода для процесса, который обычно выходит. использование –  Gilles 'SO- stop being evil' 23.08.2013, 00:53
  • 2
    @Gilles я не уверен, не важно ли это на самом деле. (Это могло бы быть, но не обязательно по причине, которую Вы подразумеваете.) Отмечают формулировку вопроса: "Если у меня есть PID процесса, который был уничтожен, как я мог бы получить статус возврата процесса?" Таким образом, процесс больше не существует к тому времени, когда OP хочет свой статус возврата, означая, что нет ничего для зацеплений к или запрос. Форма прошедшего времени "была", делает это совсем другим вопросом, чем, скажем, "как я могу получить возвращаемое значение процесса, который работает дольше, чем программа, вызывающая его?". –  a CVn 23.08.2013, 10:18
  • 3
    “Статус возврата” процесса может означать три разных вещи: 8-разрядное значение передало _exit (только если процесс, из которого выходят обычно), состояние, о котором сообщают wait и семейство (то, которое кодирует значение, передало exit если процесс обычно выходил, число сигнала, если процесс был уничтожен сигналом и еще некоторыми флагами), или сжатое 8-разрядное состояние, о котором сообщают оболочки в $? где сигналы преобразовываются в значения выше 128. Числами в вопросе автор вопроса говорил о $?, но потребности, которые будут образованы в области того, как это сделано. –  Gilles 'SO- stop being evil' 23.08.2013, 10:23

Вы хотите waitpid (), но я не знаю, доступно ли это в PHP. Не забывайте добавлять WNOHANG, если Вы не хотите, чтобы он заблокировался. Однако тот единственные работы, если PID имеет ребенка обработки вызовов.

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

1
27.01.2020, 21:53

Получение статуса выхода, если PHP больше не является родительским процессом, просто. Перенесите сценарий Python в сценарий Bash для записи статуса выхода в файле. Например:

#!/bin/bash
false # false is a program that always has an exit status of 1.
echo $? > exit_status.log

Поместит '1' в exit_status.log. Просто замена false с Вашим фактическим сценарием Python.


Инициирование сценария для выполнения, как отрицается не блокирующий процесс в фоновом режиме от PHP является более трудным. Полагайте, что инициирование процесса с Кроном планирует и избегает PHP все-вместе!

Иначе возможное решение состоит в том, чтобы назвать использование сценария at. Вот полное решение:

От вызова PHP:

<?php
exec("at -f commands now");

В файле, commands:

sleep 10 # Do nothing for 10 seconds
false # Return status 1
echo $? > exit_status.log

Если у Вас нет корневого доступа и at не установлен, затем скомпилируйте его локально в Ваш корневой каталог, при помощи чего-то как ./configure --prefix=$HOME/local. Иначе попросите, чтобы администратор установил пакет.

Дальнейшее чтение: man at, man cron

1
27.01.2020, 21:53
  • 1
    Не Был бы atd все еще потребность работать за пределами процесса веб-сервера и контекста защиты, хотя? –  a CVn 22.08.2013, 13:48
  • 2
    . Было трудно выбрать 'принятый' ответ здесь! спасибо –  dotancohen 25.08.2013, 15:39

Другая альтернатива:

От PHP:

exec("./wrapper.sh");

В wrapper.sh:

#!/bin/bash
./wrapperlogger.sh >/dev/null 2>&1 &

В wrapperlogger.sh:

./yourPythonScript
echo $? > exit_status.log

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

1
27.01.2020, 21:53
  • 1
    . Было трудно выбрать 'принятый' ответ здесь! –  dotancohen 25.08.2013, 15:42

Теги

Похожие вопросы