Отказ
Мне хорошо известно, что PHP, возможно, не был лучшим выбором в этом случае для сервера сокетов. Пожалуйста, воздержитесь от предложения разные языки/платформы - поверьте мне - я слышал это от всех направления.
Работая в Unix-среде и используя PHP 5.2.17, моя ситуация выглядит следующим образом. Я построил сервер сокетов на PHP, который обменивается данными с флеш-клиентами. Мой первый шаг состоял в том, что каждое входящее соединение блокировало последовательные соединения, пока оно не закончило обрабатываться. Я решил это, используя PHP pcntl_fork()
. Я успешно смог вызвать множество дочерних процессов (сохраняя их PID в родительском), которые занимались передачей сообщений другим клиентам и, следовательно, "освобождали" родительский процесс и позволяли ему продолжать обрабатывать следующее соединение [s].
Моя главная проблема прямо сейчас заключается в обработке/обработке с коллекцией этих мертвых/зомби-дочерних процессов и их прекращении. Я прочитал (снова и снова) соответствующие страницы руководства PHP для pcntl_fork() и понял, что родительский процесс отвечает за очистка своих детей. Родительский процесс получает SIGNAL из своего дочернего элемента, когда дочерний элемент выполняет 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]);
}
}
}
Я действительно вижу как echo, включая соответствующий и правильный дочерний 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] <defunct>
web5 5321 5234 0 14:51 ? 00:00:00 [php] <defunct>
web5 5466 5234 0 14:52 ? 00:00:00 [php] <defunct>
Как вы можете видеть, все эти процессы являются дочерними процессами родителя, у которого есть PID 5234
Я что-то пропустил в своем понимании? Кажется, мне удалось заставить все работать (и это так), но я остался с бесчисленными зомби-процессами в системе!
Мои планы на зомби-апокалипсис - твердые камни -
но что я могу сделать, когда даже sudo kill -9
не убивает дочерние процессы зомби?
Обновление через 10 дней
Я сам ответил на этот вопрос после некоторых дополнительных исследований, если вы все еще можете выдержать свои промахи продолжить.