Здравствуйте, товарищи программисты!
Возникла проблема при написании системы приложений для веб сервера, использующего CGI. Существует CGI программа, написанная на C++. Сама она запущена определенным компонентом сервера, который создает pipe'ы и делает fork&exec. Если раздвоить программу форком, то ее дочерняя ветка начинает работать и запускает другой процесс, а родительская останавливается до выхода из дочерней. Мне же нужно, что бы родительский процесс продолжал работать параллельно. Если я пробую запустить простую программу в терминале, которая делает fork и печатает какую-то информацию, то видно, что процессы работают параллельно. Почему же тогда CGI программа встает на форке? Из-за ее CGI природы? Что тогда нужно изменить, что бы после форка все снова работало параллельно?
Решено: Проблема с fork из CGI процесса
Модератор: Модераторы разделов
-
Portnov
- Модератор
- Сообщения: 1786
- Статус: Матёрый линуксоид
- ОС: Debian testing/unstable
Re: Решено: Проблема с fork из CGI процесса
"Гипотенуза". Возможно, ваше приложение пишет в сетевой сокет (или на stdout, который привязан к сетевому сокету). И пишущий поток блокирует сокет, не позволяя больше никому туда писать.
Работа: Ubuntu 9.10
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
-
fenixk19
- Сообщения: 5
- ОС: Ubuntu
Re: Решено: Проблема с fork из CGI процесса
Да, CGI программа пишет в stdout который привязан к сокету. А вот от дочернего потока мне не нужно выходной информации(у него свой сокет). Как мне все таки заставить их работать без блокировки? Можно ли вообще закрыть stdout?
-
ssh
- Сообщения: 78
- ОС: Debian
Re: Решено: Проблема с fork из CGI процесса
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 ) ;
........ // продолжение потомка
}
{
....... // продолжение папы
}
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 процесса
Нет, оно к сожалению не помогло. Как я понял, процесс на самом деле не блокируется, а нормально отрабатывает. Но вот fcgi-переходник, который общается со скриптом не отдает серверу результат до тех пор, пока не завершится потомок. Что такое есть у этого потомка, что заставляет сервер думать, что приложение еще работает? Вроде даже файловые дескрипторы закрываются. Можно ли как-нибудь сделать fork, не наследуя всякий шлак от родителя?
-
Portnov
- Модератор
- Сообщения: 1786
- Статус: Матёрый линуксоид
- ОС: Debian testing/unstable
Re: Решено: Проблема с fork из CGI процесса
Использовать непосредственно clone() (man 2 clone), явно указывая, что надо наследовать. Варнинг: работает только на линуксе.
Работа: Ubuntu 9.10
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
-
fenixk19
- Сообщения: 5
- ОС: Ubuntu
Re: Решено: Проблема с fork из CGI процесса
Это вариант, но все же я пока постараюсь обойтись без clone.
Дальнейшие мои исследования показали, что в fcgi переходнике присутствует вызов select, который обычно возвращается по завершению запущеного скрипта. Однако если скрипт делает fork, то select завершается только при завершении потомков. select проверяет дескрипторы stdout и stderr на возможность чтения. Как сделать так, чтобы select реагировал только на состояние дескрипторов скрипта, а с потомками скрипта связан не был?
Дальнейшие мои исследования показали, что в fcgi переходнике присутствует вызов select, который обычно возвращается по завершению запущеного скрипта. Однако если скрипт делает fork, то select завершается только при завершении потомков. select проверяет дескрипторы stdout и stderr на возможность чтения. Как сделать так, чтобы select реагировал только на состояние дескрипторов скрипта, а с потомками скрипта связан не был?
-
fenixk19
- Сообщения: 5
- ОС: Ubuntu
Re: Решено: Проблема с fork из CGI процесса
Проблему исправить удалось. Оказалось, в fcgi переходник нужно было добавить закрытие концов pipe'ов, после запуска dup2 с этими концами. А также закрывать stdin/err/out в самом потомке скрипта после fork.