Решено: Проблема с fork из CGI процесса

Модератор: Модераторы разделов

fenixk19
Сообщения: 5
ОС: Ubuntu

Решено: Проблема с fork из CGI процесса

Сообщение fenixk19 »

Здравствуйте, товарищи программисты!
Возникла проблема при написании системы приложений для веб сервера, использующего CGI. Существует CGI программа, написанная на C++. Сама она запущена определенным компонентом сервера, который создает pipe'ы и делает fork&exec. Если раздвоить программу форком, то ее дочерняя ветка начинает работать и запускает другой процесс, а родительская останавливается до выхода из дочерней. Мне же нужно, что бы родительский процесс продолжал работать параллельно. Если я пробую запустить простую программу в терминале, которая делает fork и печатает какую-то информацию, то видно, что процессы работают параллельно. Почему же тогда CGI программа встает на форке? Из-за ее CGI природы? Что тогда нужно изменить, что бы после форка все снова работало параллельно?
Спасибо сказали:
Аватара пользователя
Portnov
Модератор
Сообщения: 1786
Статус: Матёрый линуксоид
ОС: Debian testing/unstable

Re: Решено: Проблема с fork из CGI процесса

Сообщение Portnov »

"Гипотенуза". Возможно, ваше приложение пишет в сетевой сокет (или на stdout, который привязан к сетевому сокету). И пишущий поток блокирует сокет, не позволяя больше никому туда писать.
Работа: Ubuntu 9.10
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
Спасибо сказали:
fenixk19
Сообщения: 5
ОС: Ubuntu

Re: Решено: Проблема с fork из CGI процесса

Сообщение fenixk19 »

Да, CGI программа пишет в stdout который привязан к сокету. А вот от дочернего потока мне не нужно выходной информации(у него свой сокет). Как мне все таки заставить их работать без блокировки? Можно ли вообще закрыть stdout?
Спасибо сказали:
ssh
Сообщения: 78
ОС: Debian

Re: Решено: Проблема с fork из CGI процесса

Сообщение ssh »

if( fork() != 0 )
{
....... // продолжение папы

}
else
{
i = open( "/dev/null", O_RDWR ) ;
close( 0 ) ; dup2( i, 0 ) ;
close( 1 ) ; dup2( i, 1 ) ;
close( 2 ) ; dup2( i, 2 ) ;

........ // продолжение потомка
}
Спасибо сказали:
fenixk19
Сообщения: 5
ОС: Ubuntu

Re: Решено: Проблема с fork из CGI процесса

Сообщение fenixk19 »

Нет, оно к сожалению не помогло. Как я понял, процесс на самом деле не блокируется, а нормально отрабатывает. Но вот fcgi-переходник, который общается со скриптом не отдает серверу результат до тех пор, пока не завершится потомок. Что такое есть у этого потомка, что заставляет сервер думать, что приложение еще работает? Вроде даже файловые дескрипторы закрываются. Можно ли как-нибудь сделать fork, не наследуя всякий шлак от родителя?
Спасибо сказали:
Аватара пользователя
Portnov
Модератор
Сообщения: 1786
Статус: Матёрый линуксоид
ОС: Debian testing/unstable

Re: Решено: Проблема с fork из CGI процесса

Сообщение Portnov »

Использовать непосредственно clone() (man 2 clone), явно указывая, что надо наследовать. Варнинг: работает только на линуксе.
Работа: Ubuntu 9.10
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
Спасибо сказали:
fenixk19
Сообщения: 5
ОС: Ubuntu

Re: Решено: Проблема с fork из CGI процесса

Сообщение fenixk19 »

Это вариант, но все же я пока постараюсь обойтись без clone.
Дальнейшие мои исследования показали, что в fcgi переходнике присутствует вызов select, который обычно возвращается по завершению запущеного скрипта. Однако если скрипт делает fork, то select завершается только при завершении потомков. select проверяет дескрипторы stdout и stderr на возможность чтения. Как сделать так, чтобы select реагировал только на состояние дескрипторов скрипта, а с потомками скрипта связан не был?
Спасибо сказали:
fenixk19
Сообщения: 5
ОС: Ubuntu

Re: Решено: Проблема с fork из CGI процесса

Сообщение fenixk19 »

Проблему исправить удалось. Оказалось, в fcgi переходник нужно было добавить закрытие концов pipe'ов, после запуска dup2 с этими концами. А также закрывать stdin/err/out в самом потомке скрипта после fork.
Спасибо сказали: