Отказ от ответственности
Я прекрасно понимаю, что PHP, возможно, не был лучшим выбором в данном случае для сокет-сервера. Пожалуйста, воздержитесь от предложения разные языки/платформы - поверьте мне - я слышал это от всех направления.
Работая в среде Unixи используя PHP 5.2.17, моя ситуация выглядит следующим образом: я создал сокет-сервер на PHP, который взаимодействует с флэш-клиентами. Моя первая проблема заключалась в том, что каждое входящее соединение блокировало последующие соединения до тех пор, пока не завершится его обработка. Я решилэту проблему с помощью PHP
pcntl_fork()
. Мне удалось успешно создать множество дочерних процессов (сохранив их PID в родительском), которые позаботились о широковещательной передаче сообщений другим клиентам и, следовательно, «освободили» родительский процесс и позволили ему продолжать обрабатывать следующее соединение [я].Моей основной задачей сейчас является работа с коллекцией этих мертвых/зомби дочерних процессов и их завершение. Я прочитал (снова и снова) соответствующие страницы руководства по PHP для pcntl_fork()и понял, что родительский процесс отвечает за очистку своих дочерних процессов. Родительский процесс получает СИГНАЛ от своего дочернего процесса, когда дочерний процесс выполняет
exit(0)
.Я могу «поймать» этот сигнал с помощью функцииpcntl_signal()
для настройки обработчика сигнала .Мой signal_handler выглядит следующим образом:
declare(ticks = 1); function sig_handler($signo){ global $forks; // this is an array that holds all the child PID's foreach($forks AS $key=>$childPid){ echo "has my child {$childPid} gone away?".PHP_EOL; if (posix_kill($childPid, 9)){ echo "Child {$childPid} has tragically died!".PHP_EOL; unset($forks[$key]); } } }
Я действительно вижу оба эха, включая соответствующий и правильный дочерний PID, который необходимо удалить, но кажется, что
posix_kill($childPid, 9)
Который, как я понимаю, является синонимом
kill -9 $childPid
возвращает TRUE, хотя на самом деле НЕ удаляет процесс...Взято из man-страниц
posix_kill
:Возвращает TRUE в случае успеха или FALSE в случае неудачи.
Я отслеживаю дочерние процессы с помощью команды
ps
. В системе они выглядят следующим образом:web5 5296 5234 0 14:51 ? 00:00:00 [php]
web5 5321 5234 0 14:51 ? 00:00:00 [php] web5 5466 5234 0 14:52 ? 00:00:00 [php] Как вы можете видеть, все эти процессы являются дочерними процессами родителя с PID
5234
Я что-то упустил в своем понимании? Кажется, мне удалось заставить все работать (и это работает), но у меня осталось бесчисленное количество зомби-процессов в системе!
Мои планы на зомби-апокалипсис тверды, как скала -
но что я могу сделать, если дажеsudo kill -9
не убивает дочерние процессы-зомби?Обновление через 10 дней
Я сам ответил на этот вопрос после некоторых дополнительных исследований, если вы все еще в состоянии выносить мои бредни продолжайте по своему желанию.