URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID8
Нить номер: 5794
[ Назад ]

Исходное сообщение
"Как отключить чайлда от STDOUT в PHP?"

Отправлено mac , 04-Июн-08 10:39 
Пхп собран как модуль апача под *nix. Есть задачка - запустить чайлдом очень долгий процесс, и чтобы родитель его соотв-но не ждал. Но как отрубить чайлда от STDOUT?? Браузер всёравно ждёт пока чайлд завершится и закроет канал ((
Неужели обязательно нужно длинную рутину делать отдельным скриптом и пускать через exec(long.php > /dev/null > 2>&1 &)?


Содержание

Сообщения в этом обсуждении
"Как отключить чайлда от STDOUT в PHP?"
Отправлено Pahanivo , 06-Июн-08 09:54 
>Пхп собран как модуль апача под *nix. Есть задачка - запустить чайлдом
>очень долгий процесс, и чтобы родитель его соотв-но не ждал. Но
>как отрубить чайлда от STDOUT?? Браузер всёравно ждёт пока чайлд завершится
>и закроет канал ((
>Неужели обязательно нужно длинную рутину делать отдельным скриптом и пускать через exec(long.php > /dev/null > 2>&1 &)?

Чето я непонял каким местом тут STDOUT в связке php(mod)+apache ?


"Как отключить чайлда от STDOUT в PHP?"
Отправлено mac , 06-Июн-08 10:42 
>
>Чето я непонял каким местом тут STDOUT в связке php(mod)+apache ?

Может я неправильно понимаю, я полагал что php(mod) тоже делает вывод в STDOUT как и php(cgi). Но смысл остаётся тот же. Как сделать так чтоб браузер не ждал чайлда?



"Как отключить чайлда от STDOUT в PHP?"
Отправлено angra , 06-Июн-08 11:01 
А какие действия у вас предпринимает child для своей демонизации?



"Как отключить чайлда от STDOUT в PHP?"
Отправлено mac , 06-Июн-08 11:53 
>А какие действия у вас предпринимает child для своей демонизации?

Да собственно я и не знаю какие действия он должен предпринять, в этом и дело наверное. Перед форком я делаю ob_end_flush(), чтобы чайлд не выводил никаких заголовков в браузер. После форка родитель завершает работу, выдаёт браузеру контент, а чайлд должен продолжать заниматься своими делами, но браузер всёравно ждёт пока и он прекратит работу.



"Как отключить чайлда от STDOUT в PHP?"
Отправлено angra , 07-Июн-08 06:19 
Обычно происходит так: браузер ждет окончания данных от веб-сервера, веб-сервер ждет завершения скрипта-родителя, родитель ждет завершения потомка. Если же надо отвязать потомка от родителя, то есть произвести демонизацию, то следует в потомке закрыть дескрипторы стандартного ввода/вывода(STDIN, STDOUT,STDERR они же 0,1,2) и вызвать setsid для отвязывания от терминала(и родителя). Есть ли в php такие возможности я не в курсе. Более подробно о демонизации можно глянуть, например, здесь http://www.enderunix.org/documents/eng/daemon.php ну или гугл поспрашивать.

"Как отключить чайлда от STDOUT в PHP?"
Отправлено GD , 07-Июн-08 08:55 
>Обычно происходит так: браузер ждет окончания данных от веб-сервера, веб-сервер ждет завершения
>скрипта-родителя, родитель ждет завершения потомка. Если же надо отвязать потомка от
>родителя, то есть произвести демонизацию, то следует в потомке закрыть дескрипторы
>стандартного ввода/вывода(STDIN, STDOUT,STDERR они же 0,1,2) и вызвать setsid для отвязывания
>от терминала(и родителя). Есть ли в php такие возможности я не
>в курсе. Более подробно о демонизации можно глянуть, например, здесь http://www.enderunix.org/documents/eng/daemon.php
>ну или гугл поспрашивать.

осталось понять как отвязать апач от апача
(мы же обсуждаем apache+mod_php)


"Как отключить чайлда от STDOUT в PHP?"
Отправлено mac , 07-Июн-08 12:22 
>Обычно происходит так: браузер ждет окончания данных от веб-сервера, веб-сервер ждет завершения
>скрипта-родителя, родитель ждет завершения потомка. Если же надо отвязать потомка от
>родителя, то есть произвести демонизацию, то следует в потомке закрыть дескрипторы
>стандартного ввода/вывода(STDIN, STDOUT,STDERR они же 0,1,2) и вызвать setsid для отвязывания
>от терминала(и родителя). Есть ли в php такие возможности я не
>в курсе. Более подробно о демонизации можно глянуть, например, здесь http://www.enderunix.org/documents/eng/daemon.php
>ну или гугл поспрашивать.

Спасибо за инфу, действительно в обычном случае (cgi) так и есть и оно работает. А тут закрыть STDOUT не получается. Наверное всётаки нужно делать чайлдовую рутину отдельным скриптом и пускать через exec("nohup ..."), чтоб апач не форкался. А жаль, удобнее было б всё в одном скрипте иметь.


"Как отключить чайлда от STDOUT в PHP?"
Отправлено Pahanivo , 07-Июн-08 14:36 
хочетсо добавить это есть потенциальный DoS!
буть осторожней


"Как отключить чайлда от STDOUT в PHP?"
Отправлено mac , 07-Июн-08 15:06 
>хочетсо добавить это есть потенциальный DoS!
>буть осторожней

Это для админки сайта, такой сценарий маловероятен. Но сенк за предупреждение, всё надо учитывать.



"Как отключить чайлда от STDOUT в PHP?"
Отправлено angra , 07-Июн-08 21:46 
Может лучше запустить демон не из апача и обращаться к нему из скрипта через сокет с запросами?

"Как отключить чайлда от STDOUT в PHP?"
Отправлено mac , 07-Июн-08 23:31 
>Может лучше запустить демон не из апача и обращаться к нему из
>скрипта через сокет с запросами?

Из всего вышесказанного делаю вывод что нужно делать exec отдельного скрипта, а обращаться потом к чайлду не нужно, он отработал своё и всё, он вроде как и не совсем демон )).


"Как отключить чайлда от STDOUT в PHP?"
Отправлено angra , 08-Июн-08 08:38 
Объясню подробней. Создается демон, который в цикле слушает сокет при помощи select и если нет данных и текущих заданий засыпает на определенное время. То есть в режиме бездействия системных ресурсов не жрет. Различные вебскрипты для выполнения фоновых задач или задач, требующих повышения привилегий, связываются через сокет с демоном и вызывают ту или иную его функцию. Демон выполняет поставленную задачу, попутно продолжая проверку сокета на предмет новых соединений. Если вам нужно вызвать один единственный скрипт, не требующий повышения привилегий, причем очень редко, то можно обойтись и фоновым запуском, однако если возможных заданий становится несколько, становится критичным race condition и время выполнения, появляется нужда в опросе статуса выполнения задания, необходимость в повышении привелегий итд итп, то вариант с демоном будет значительно удобней.


"Как отключить чайлда от STDOUT в PHP?"
Отправлено mac , 08-Июн-08 21:01 
>[оверквотинг удален]
>и если нет данных и текущих заданий засыпает на определенное время.
>То есть в режиме бездействия системных ресурсов не жрет. Различные вебскрипты
>для выполнения фоновых задач или задач, требующих повышения привилегий, связываются через
>сокет с демоном и вызывают ту или иную его функцию. Демон
>выполняет поставленную задачу, попутно продолжая проверку сокета на предмет новых соединений.
>Если вам нужно вызвать один единственный скрипт, не требующий повышения привилегий,
>причем очень редко, то можно обойтись и фоновым запуском, однако если
>возможных заданий становится несколько, становится критичным race condition и время выполнения,
>появляется нужда в опросе статуса выполнения задания, необходимость в повышении привелегий
>итд итп, то вариант с демоном будет значительно удобней.

Спасибо, как-то не задумывался над этим. Большое спасибо! Есть смысл сочинить демона на будущее.