Я использую компонент Symfony2 Process для управления пулом процессов вручную.Symfony2 Process component - невозможно создать канал и запустить новый процесс
В приведенном ниже примере я перезапускаю 2 простых процесса каждые 2 секунды и отслеживаю, что происходит. Приложение прерывается после перезапуска этих процессов несколько сотен раз.
Выполнение останавливается, и я получаю следующее предупреждение PHP:
proc_open(): unable to create pipe Too many open files
, а затем следующее исключение выбрасывается компонентом Symfony процесса:
[Symfony\Component\Process\Exception\RuntimeException]
Unable to launch a new process.
Я вручную контролировать общее количество открытых процессов, и он никогда не поднимается до ожидаемого предела.
Ниже упрощена фрагмент является частью команды Symfony2 и будучи запущенной из командной строки (например, приложение/консоль хомяк: бег):
$processes[] = new Process("ls > /dev/null", null, null, null, 2);
$processes[] = new Process("date > /dev/null", null, null, null, 2);
while (count($processes) > 0) {
foreach ($processes as $i => $process) {
if (!$process->isStarted()) {
$process->start();
continue;
}
try {
$process->checkTimeout();
} catch (\Exception $e) {
// Don't stop main thread execution
}
if (!$process->isRunning()) {
// All processes are timed out after 2 seconds and restarted afterwards
$process->restart();
}
}
usleep($sleep * 1000000);
}
Это приложение выполняется на сервере MAC под управлением OS X 10.8.4.
Буду признателен за то, как преследовать корень этой проблемы.
Update # 1: я упростил свою функцию, чтобы работать с основными командами, как ls
и date
для быстрого тестирования. По-прежнему выглядит, что команда Process не работает после запуска и остановки около 1000-1500 процессов.
Я подозревал, что proc_close()
не был вызван правильно для каждого процесса, но дальнейшее расследование показало, что здесь не так.
Хороший вопрос. Я не рассматривал необходимость ручного вызова сборщика мусора. Выполнение некоторых дополнительных тестов (перезапуск процессов 100 000 раз) с помощью 'gc_collect_cycles()' подтвердил ваше решение. Благодаря! – ukliviu
лучшим способом было бы - - stop (0) 'экземпляр процесса, когда это было сделано, это эффективно закрыло бы дескрипторы открытого файла, не полагаясь на' __destruct', вызываемый сборщиком мусора. – Florian