PHP - Уничтожение дочернего процесса, запущенного pcntl_fork - PullRequest
7 голосов
/ 12 ноября 2009

Я использую pcntl_fork, чтобы запустить дочерний процесс для отправки электронной почты через SMTP.

Дочерний процесс использует пакет PEAR Mail для отправки электронной почты, но проблема в том, что если удаленный сервер не отвечает, процесс просто вечно ожидает ответа, независимо от ограничения по времени, установленного в php.ini. .

Чтобы обойти это, я использую функцию pcntl_alarm для запуска функции через 30 секунд, которая убивает дочерний процесс, если он все еще выполняется.

function handlesig($sig) {
    global $pid,$node,$resend;
    posix_kill($pid,SIGKILL);
    mysql_query("insert into log (event) values ('Timed out!')");
}

Когда я убиваю дочерний процесс, я остаюсь с несуществующим процессом в системе.

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

Ответы [ 5 ]

5 голосов
/ 21 декабря 2009

Вам нужно либо подождать, как описано выше, либо заставить дочерний процесс отсоединиться от родителя с помощью posix_setsid

4 голосов
/ 11 декабря 2009

Если у вас есть дети-зомби, это значит, что вы не wait для них. Не эксперт по PHP, но системный вызов waitpid(2). например звоните

waitpid(-1, NULL, WNOHANG);

время от времени или всякий раз, когда вы получаете SIGCHILD. Каждый звонок будет пожинать до одного зомби. WNOHANG возвращает его сразу же, а не блокирует, если у него нет дочерних элементов.

На справочной странице wait есть хороший раздел с заметками о том, как все это работает ...

1 голос
/ 18 декабря 2009

Чтобы завершить ответ Питера, взгляните на pcntl_waitpid

Просто нужно сделать это после убийства: pcntl_waitpid($pid)

1 голос
/ 16 ноября 2009
exec(PATH_TO_PHP . " email_script.php $params > /dev/null 2>&1 &");

Таким образом, родитель не ждет ответа от ребенка, и у вас нет зомби. В email_script.php обработайте отправку электронной почты и зарегистрируйте ответ на файл, который вы можете проанализировать из родительского скрипта или что нет.

1 голос
/ 12 ноября 2009

Нормальным решением этой проблемы является использование хорошо настроенного локального хост-реле. Что я обычно делаю, так это настройку локального хостинга с использованием постфикса.

Затем я отправлю электронное письмо местному ретранслятору, который поставит его в очередь и отправит получателю как можно скорее.

Хорошая особенность отправки этого сообщения в локальный ретранслятор состоит в том, что вы можете настроить его для пересылки электронной почты и других ответов.

Для вас вопрос о несуществующей, насколько я знаю, является ли SIGKILL очень сложным способом завершения процесса, вы пробовали (SIGSTOP или SIGTSTP)?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...