LINUX.ORG.RU

fork + файловые дескрипторы


0

2

Можно ли запретить наследовать дескрипторы?

Конечно подобную ситуацию в большинстве случаев можно красиво избежать, но часто происходит следующее -

Дочерний процесс умирает, закрывает какой-то дескриптор, при закрытии дескриптора вызывается какой-нибудь деструктор, который отправляет в этот дескриптор команду disconnect, либо срабатывает какой-нибудь select с теми же последствиями.

Можно ли сделать так, чтобы дочерний процесс не наследовал дескрипторы?

★★★★

Ответ на: комментарий от dmsh

Хм, посмотрю.. А может есть более переносимое решение? Я кстати не уверен что в моем ЯП без магии будет доступ к clone. Да и платформа сменится может..

OxiD ★★★★
() автор топика

> Можно ли сделать так, чтобы дочерний процесс не наследовал дескрипторы?

в линуксе? да, можно.

arsi ★★★★★
()
Ответ на: комментарий от OxiD

Кстати, clone вроде этого не умеет, флаг CLONE_FILES это нечто другое, и более того было бы удобнее запрещать наследовать не все|, а только некоторые дкскрипторы. скажем STDIN хотелось бы оставить, а соединие с базой прибить.

Пример из жизни - етсь цикл который получает данные из mysql, при этом использует mysql_use_result - т.е данные читаются иобрабатываются из сервера строка за строкой.

После получения очередной порции отфоркивается ребенок который эти данные как-то переваривает. После смерти демона родитель падает с ошибкой mysql gone away.

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

OxiD ★★★★
() автор топика
Ответ на: комментарий от OxiD

> Я всегда думал что это закроет дескриптор при вызове exec() ;)

так и есть. ели ты знаешь свер™секретный®способ© порождения потомков без вызова fork+exec?

arsi ★★★★★
()
Ответ на: комментарий от OxiD

Я не понял до конца, что ты хочешь сделать, но, похоже, что ты решаешь не ту проблему. Ты уверен что именно магические манипуляции с дескрипторами тебе помогут?

dmsh
()
Ответ на: комментарий от geekless

на вопрос отвечает К.О.

> Хм, у ТСа ни слова про exec.

зато у меня есть. почему? потому, что у ТСа есть много слов про дочерние процессы.

arsi ★★★★★
()
Ответ на: на вопрос отвечает К.О. от arsi

> потому, что у ТСа есть много слов про дочерние процессы.

Дочерний процесс никак не связан с exec. fork — это уже дочерний процесс.

Что касается архитектуры приложения ТСа... Ну может он форкается и передаёт управление в большой-пребольшой сторонний *.so. Мало ли извращений на свете. :)

geekless ★★
()
Ответ на: комментарий от arsi

Зачем тебе столько скобочек? Лиспер что ли?

> неужели?))))

Неужели. Дочерний процесс порождается форком. А exec запускает в процессе новый бинарник, без каких-либо порождений новых процессов. Вроде сам не маленький, матчасть знать должен.

geekless ★★
()
Ответ на: комментарий от arsi

Да, так точно, exec никак не связан с запуском дочернего процесса.. он запускает бинарники, а форк делает дочку..

OxiD ★★★★
() автор топика

>закрывает какой-то дескриптор, при закрытии дескриптора вызывается какой-нибудь деструктор,
Какая связь между дескрипторами и деструкторами кроме похожести слов? Дескрипторы - наследуются. Но их можно спокойно закрывать сразу после открытия без каких-либо последствий.

Vamp
()
Ответ на: комментарий от Vamp

такая связь что у меня есть обьект класса DB_HANDLE который имеет деструктор, и когда я его закрываю, или когда он разрушается по выходе из области видимости, или когда программа заканчивает работу, etc вызывается деструктор, который отключает мне родитель (он пишет в дескриптор сообщение disconnect) ;)

OxiD ★★★★
() автор топика
Ответ на: комментарий от OxiD

Вот об этом я и говорил. Пляски с дескрипторами тебе не помогут, БД на том конце ничего не знает про твои процессы и дескрипторы, ей наплевать. Она закроет соединение как только получит соответствующее сообщение.

Тебе надо реорганизовать саму программу так, чтобы дочерний процесс соединение не прибивал.

dmsh
()
Ответ на: комментарий от OxiD

Ну о чем и речь. Проблема не в наследовании дескрипторов, а в том, что у тебя вызывается деструктор объекта.
Соответственно, решение номер один - добавить в объект метод для его «обезвреживания», так, чтобы деструктор не закрывал соединение.
Вариант два - вызвать exec() сразу после fork().
Вариант три - если объект типа DB_HANDLE автоматический, то можно завершать программу «нечестно» - вызывая exit(). При этом не вызываются деструкторы для автоматических объектов.

Vamp
()
Ответ на: комментарий от Vamp

> Вариант четыре — исправить архитектуру приложения, чтобы кто попало не закрывал соединения к базе данных.

geekless ★★
()
Ответ на: комментарий от geekless

Это как раз может оказаться сделать не очень просто. Если есть объект, деструктор которого железно закрывает соединение, и есть форк, то деструктор с высокой долей вероятности в потомке таки вызовется - если не делать специальных телодвижений, см. выше.

Vamp
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.