PHP 4 и 5, Ctrl-C, system () и дочерние процессы - PullRequest
1 голос
/ 03 октября 2008

У меня есть PHP-скрипт, который использует вызов system() для выполнения других (потенциально длительных) программ (для интереса: NCBI BLAST, phrap, primer3 и другие программы для анализа и сборки последовательности ДНК).

Я работаю под Windows XP, использую версию CLI PHP из командной строки или в качестве службы. (В любом случае я общаюсь с ним через очередь задач в таблице базы данных).

Под PHP4: когда я нажимаю Ctrl + C , сценарий останавливается, и любой дочерний процесс, запущенный в то время, также останавливается. Под PHP5: когда я нажимаю Ctrl + C , сценарий останавливается, но дочерний процесс остается запущенным.

Аналогично, при запуске сценария как службы остановка службы при запуске его с PHP4 останавливает дочерний процесс, а с PHP5 дочерний процесс продолжает работать.

Я попытался написать минимальное тестовое приложение и обнаружил такое же поведение. Тестовый PHP-скрипт просто использует system () для выполнения программы на C (которая просто спит в течение 30 секунд), а затем ожидает нажатия клавиши.

Я взглянул на исходный код PHP 4.4.9 и 5.2.6, но не увидел различий в коде system (), который выглядел так, как будто это могло вызвать это. Я также быстро взглянул на код запуска приложения CLI и не увидел различий в обработке сигналов.

Будем благодарны за любые подсказки о том, что могло вызвать это, или обойти это решение.

Спасибо.

Ответы [ 2 ]

1 голос
/ 13 октября 2008

Вместо использования system () посмотрите на proc_open () , proc_close () и proc_terminate () .

1 голос
/ 03 октября 2008

Эта проблема возникает как минимум в PHP 5.1.2.

Когда SIGINT отправляется через CTRL + C или CTRL + BREAK, вызывается обработчик. Если этот обработчик отправляет SIGTERM другим дочерним элементам, сигналы не принимаются.

SIGINT можно отправить с помощью posix_kill (), и он работает точно так же, как и ожидалось - это применимо только в том случае, если инициируется через жесткий перерыв.

От: http://php.oregonstate.edu/manual/en/function.pcntl-signal.php

В документе есть пример кода для перехвата CTRL + C и отправки posix_kill детям. В нем много другого кода и информации о дочерних процессах и сигналах.

...