- Треды + fork, anonymous, 08:07 , 27-Мрт-09 (1)
>[оверквотинг удален] >контролировать их выполнение. Возникает такая ситуация: по TCP этому приложению отправляется >запрос, на который оно успешно fork'ает ребенка, отвечает `ok' и закрывает >сокет. Проблема в том, что сокет не закрывается, по всей видимости >из-за того, что при fork дескриптор сокета наследуется. Вопрос: как корректно >закрыть все родительские дескрипторы в ребенке? > >1. Вести учет открытых файловых дескрипторов по всему приложению я, разумеется, не >собираюсь, по этой же причине никаких FD_CLOEXEC. >2. Нужно кроссплатформенное решение. Есть unshare, но это только Linux; есть rfork, >но это только FreeBSD. 1. Есть shutdown() 2. п. 1 не спасёт от небходимости закрывать дескриптор в parent --- иначе потекут дескрипторы, а это ограниченный ресурс. 3. Аффтору убить себя ап стену.
- Треды + fork, const86, 11:19 , 27-Мрт-09 (2)
>3. Аффтору убить себя ап стену. Зря вы так. С клиентским сокетом действительно всё просто: форкнулись, в родительском процессе закрыли, в дочернем общаемся с клиентом. Но есть интересный момент с другими файлами, которые могли наоткрываться в родительском процессе, особенно в других потоках. Они останутся в дочернем. Вроде как не особо и мешает это, но всё же лучше бы их тоже закрывать.
- Треды + fork, vic, 13:33 , 27-Мрт-09 (3)
>>3. Аффтору убить себя ап стену. > >Зря вы так. С клиентским сокетом действительно всё просто: форкнулись, в родительском >процессе закрыли, в дочернем общаемся с клиентом. Но есть интересный момент >с другими файлами, которые могли наоткрываться в родительском процессе, особенно в >других потоках. Они останутся в дочернем. Вроде как не особо и >мешает это, но всё же лучше бы их тоже закрывать. Не зря :) автор же написал: >1. Вести учет открытых файловых дескрипторов по всему приложению я, разумеется, не >собираюсь, по этой же причине никаких FD_CLOEXEC.
- Треды + fork, Petr, 15:51 , 27-Мрт-09 (5)
>Не зря :) автор же написал: >>1. Вести учет открытых файловых дескрипторов по всему приложению я, разумеется, не >>собираюсь, по этой же причине никаких FD_CLOEXEC. Вы что же, не согласны, что это угрёбищное решение? Хотя бы потому, что в проекте используются закрытые библитеки, которые файлы открывают, а вот впихнуть в них fcntl - звиняйте. Поэтому я просил решение, а не костыль.
- Треды + fork, vic, 16:29 , 27-Мрт-09 (7)
>>Не зря :) автор же написал: >>>1. Вести учет открытых файловых дескрипторов по всему приложению я, разумеется, не >>>собираюсь, по этой же причине никаких FD_CLOEXEC. > >Вы что же, не согласны, что это угрёбищное решение? Хотя бы потому, >что в проекте используются закрытые библитеки, которые файлы открывают, а вот >впихнуть в них fcntl - звиняйте. Поэтому я просил решение, а >не костыль. Не следить за дескрипторами это и есть 'угрёбищное' решение. Использовать для всех управляемых дескрипторов флаг FD_CLOEXEC, это нормальное корректное решение. Ни разу не костыль. Для неуправляемых по какой-либо причине дескрипторов следует предпринять попытки сделать их управляемые и далее см. выше. Иначе возможно использование следующего приема: // в случае отсутствия getdtablesize() можно использовать макрос MAX_FD for (int i_fd = getdtablesize()-1; i_fd > 2; --i_fd) close(i_fd); // оставили 0,1,2 А также есть интересный для изучения каталог /proc/self/fd, но он может быть не везде. Прием никаким образом не спасает от неопределенного поведения модулей кода которые зависят от закрытых, в обход этих модулей, дескрипторов. Кросплатформенного решения в данном случае не может быть, слишком разные платформы, тем более никому не ясен ваш список ОС :)
- Треды + fork, Petr, 17:39 , 27-Мрт-09 (8)
>Не следить за дескрипторами это и есть 'угрёбищное' решение. > >Использовать для всех управляемых дескрипторов флаг FD_CLOEXEC, это нормальное корректное решение. Ни >разу не костыль.Это именно костыль, потому закрывать или не закрывать дескрипторы при exec - это исключительно дело кода, вызывающего exec, а не кода, работающего с этими дескрипторами. Простой пример - после форка я могу exec'нуть как кусок себя, который ожидает открытый 3, так и стороннюю программу, где должно быть закрыто все. И что, cloexec или не cloexec? Про чужой код я уже упомянул - ваши `следует предпринять попытки' из области фантастики. Вы предлагаете лезть во _все_ компоненты, и втыкать туда fcntl, тогда как решение - закрывать или не закрывать, принимается все равно перед fork'ом или exec'ом. >// в случае отсутствия getdtablesize() можно использовать макрос MAX_FD >for (int i_fd = getdtablesize()-1; i_fd > 2; --i_fd) close(i_fd); // оставили 0,1,2 Да, мне это по началу казалось костылем, но, видимо, так оно и делается. В man close, оказывается, написано кое-что по этому поводу, а также про cloexec. В кратце - закрывайте close'ом, а если нужно закрыть при exec'е, но оставить, если exec обломится, юзайте FD_CLOEXEC.
- Треды + fork, Petr, 15:43 , 27-Мрт-09 (4)
>1. Есть shutdown() >2. п. 1 не спасёт от небходимости закрывать дескриптор в parent --- >иначе потекут дескрипторы, а это ограниченный ресурс.shutdown не то. Нужно _закрыть_ в ребенке все, кроме 0,1,2. TCP соединение обрабатывается в родителе, в котором все, что нужно, закрывается. >3. Аффтору убить себя ап стену. Детский сад...
- Треды + fork, const86, 16:09 , 27-Мрт-09 (6)
> Нужно _закрыть_ в ребенке все, кроме 0,1,2.Можно посмотреть свой RLIMIT_NOFILE и пробежаться в цикле, всё поcloseить. Смутно припоминается, что это как-то вроде можно побыстрее сделать, но не могу вспомнить.
- Треды + fork, svn, 23:08 , 27-Мрт-09 (9)
>shutdown не то. Нужно _закрыть_ в ребенке все, кроме 0,1,2.Закрой в себе сначала всё плохое и ненужное, а потом делай детей.
- Треды + fork, Аноним, 17:35 , 29-Мрт-09 (10)
>Закрой в себе сначала всё плохое и ненужное, а потом делай детей. Универсальный ответ. Напиши его во все темы на этом форуме и застрелись, идиот :))
|