PHP: как сохранить доступ к вводу / выводу в parent после завершения дочернего процесса pcntl_fork ()?

661
Stilez

Я использую PHP и pcntl_fork (). Идея состоит в том, что родитель разветвляется и делает паузу для завершения ребенка; ребенок выполняет задание, затем завершается; родитель может проверить код возврата для задачи или состояние дочернего процесса и продолжить соответствующим образом.

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

Таким образом, проблема в том, что после pcntl_fork () оба процесса совместно используют одни и те же дескрипторы ввода-вывода STDXXX, поэтому, как только дочерний процесс завершает свою задачу, ввод-вывод, который он использует, как обычно, закрывается, и поэтому они закрываются для родителя как ну, это означает, что такие вещи, как echo (), используемые для продолжения взаимодействия с родителем, тоже внезапно перестают работать.

Я следую совету на php.net и использую posix kill -9 в дочернем элементе вместо exit, так что дочерний процесс завершается без закрытия IO, совместно используемого (и необходимого) для родителя, но есть более удобный способ сделать это ?

Спасибо!

0
Хм, дескрипторы файлов Unix _не_ совместно используются в fork (), и ни один из объектов PHP IO ... Так что причина более сложная, чем это. grawity 8 лет назад 0

1 ответ на вопрос

0
meuh

Before the pcntl_fork() you can "dup" the file desired file descriptors by opening for example php://stdout and php://stderr, or php://fd/3. See php protocols.


Note that when a child closes a file descriptor, it is not closed in the parent. After a fork the processes share the same pointer to open files, but you still be able to echo from the parent after the child has exited.

Это звучит многообещающе, но такие области, как сеансы и требуемые манипуляции с дескрипторами dup'ed STDXXX, немного выходят за рамки моей текущей области знаний, и страницы (на php.net и opengropup.org) не так ясны для меня, как я надеюсь. Не могли бы вы объяснить, как это сделать, на коротком «наброске» примера? Это очень помогло бы. Stilez 8 лет назад 0
@Stilez при перечитывании вашего поста Я не уверен, почему вам нужно делать что-то особенное, так как `close ()` в дочернем элементе не влияет на родительскую копию дескриптора файла. `pcntl_fork ()` должен вызывать реальную систему `fork ()`, которая эффективно выполняет `dup ()` для открытых файлов. meuh 8 лет назад 0
Я посмотрел, но php.net, похоже, не распознает close () как команду? Ясно, что когда я заменяю exit () или die () в дочернем элементе на самоуничтожение POSIX -9, родитель может продолжить вывод с помощью echo, а если нет, то очистка выполняется во время очистки. нормальный выход ребенка должен как-то закрывать или влиять на дескрипторы STDXXX, используемые родителем. Можно ли опубликовать краткий план того, как по-другому выйти из потомка, или дублировать, или «разделить», или разбить дескрипторы, чтобы выход ребенка не имел такого эффекта? Это действительно помогло бы. Stilez 8 лет назад 0
@Stilez Я попробовал небольшой cgi с ребенком, выполняющим выход, и родитель смог продолжить делать эхо (с PHP / 5.5.24 на linux), поэтому я не могу помочь в вашей ситуации. Возможно, ваш ребенок отправляет обратно заголовок `Content-Length:` с количеством байтов, которые написал ребенок. Большинство браузеров уважают эту длину и не читают за ее пределами, даже если родительский php действительно смог записать больше данных. meuh 8 лет назад 0