У меня есть сценарий PHP, который использует вызов system() для выполнения других (потенциально длительных) программ (для интереса: NCBI BLAST, phrap, primer3 и другие программы для анализа и сборки последовательности ДНК).
Я работаю под Windows XP, использую версию PHP с интерфейсом командной строки из командной строки или как службу. (В любом случае я общаюсь с ним через очередь задач в таблице базы данных).
В PHP4: когда я нажимаю Ctrl + C, скрипт останавливается, и любой дочерний процесс, запущенный в то время, также останавливается. В PHP5: когда я нажимаю Ctrl + C, скрипт останавливается, но потомок остается запущенным.
Точно так же при запуске скрипта в качестве службы остановка службы при запуске с PHP4 останавливает дочерний элемент, а с PHP5 дочерний элемент продолжает работать.
Я попытался написать минимальное тестовое приложение и обнаружил такое же поведение. Тестовый сценарий PHP просто использует system () для выполнения программы на C (которая просто спит в течение 30 секунд), а затем ожидает нажатия клавиши.
Я просмотрел исходный код PHP 4.4.9 и 5.2.6, но не увидел различий в коде system (), которые, похоже, могли бы вызвать это. Я также быстро взглянул на код запуска приложения CLI и не заметил никаких различий в обработке сигналов.
Мы будем благодарны за любые подсказки о том, что могло вызвать это, или обходной путь.
Спасибо.
Поведение PHP 4 - дети тоже останавливаются.






Эта проблема возникает как минимум в 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 детям. В нем много другого кода и информации о дочерних прецессах и сигналах.
Вместо использования system () взгляните на proc_open (), proc_close () и proc_terminate ().
Какое поведение является желаемым?