The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"Треды + fork"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [ Отслеживать ]

"Треды + fork"  
Сообщение от Petr (??) on 27-Мрт-09, 01:54 
Есть достаточно сложное многопотоковое приложение. Оно должно иногда запускать дочерние процессы и контролировать их выполнение. Возникает такая ситуация: по TCP этому приложению отправляется запрос, на который оно успешно fork'ает ребенка, отвечает `ok' и закрывает сокет. Проблема в том, что сокет не закрывается, по всей видимости из-за того, что при fork дескриптор сокета наследуется. Вопрос: как корректно закрыть все родительские дескрипторы в ребенке?

1. Вести учет открытых файловых дескрипторов по всему приложению я, разумеется, не собираюсь, по этой же причине никаких FD_CLOEXEC.
2. Нужно кроссплатформенное решение. Есть unshare, но это только Linux; есть rfork, но это только FreeBSD.

Высказать мнение | Ответить | Правка | Cообщить модератору

 Оглавление

  • Треды + fork, anonymous, 08:07 , 27-Мрт-09, (1)  
    • Треды + fork, const86, 11:19 , 27-Мрт-09, (2)  
    • Треды + fork, Petr, 15:43 , 27-Мрт-09, (4)  
      • Треды + fork, const86, 16:09 , 27-Мрт-09, (6)  
      • Треды + fork, svn, 23:08 , 27-Мрт-09, (9)  
        • Треды + fork, Аноним, 17:35 , 29-Мрт-09, (10)  

Сообщения по теме [Сортировка по времени | RSS]


1. "Треды + fork"  
Сообщение от anonymous (??) on 27-Мрт-09, 08:07 
>[оверквотинг удален]
>контролировать их выполнение. Возникает такая ситуация: по TCP этому приложению отправляется
>запрос, на который оно успешно fork'ает ребенка, отвечает `ok' и закрывает
>сокет. Проблема в том, что сокет не закрывается, по всей видимости
>из-за того, что при fork дескриптор сокета наследуется. Вопрос: как корректно
>закрыть все родительские дескрипторы в ребенке?
>
>1. Вести учет открытых файловых дескрипторов по всему приложению я, разумеется, не
>собираюсь, по этой же причине никаких FD_CLOEXEC.
>2. Нужно кроссплатформенное решение. Есть unshare, но это только Linux; есть rfork,
>но это только FreeBSD.

1. Есть shutdown()
2. п. 1 не спасёт от небходимости закрывать дескриптор в parent --- иначе потекут дескрипторы, а это ограниченный ресурс.
3. Аффтору убить себя ап стену.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

2. "Треды + fork"  
Сообщение от const86 (ok) on 27-Мрт-09, 11:19 
>3. Аффтору убить себя ап стену.

Зря вы так. С клиентским сокетом действительно всё просто: форкнулись, в родительском процессе закрыли, в дочернем общаемся с клиентом. Но есть интересный момент с другими файлами, которые могли наоткрываться в родительском процессе, особенно в других потоках. Они останутся в дочернем. Вроде как не особо и мешает это, но всё же лучше бы их тоже закрывать.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

3. "Треды + fork"  
Сообщение от vic (??) on 27-Мрт-09, 13:33 
>>3. Аффтору убить себя ап стену.
>
>Зря вы так. С клиентским сокетом действительно всё просто: форкнулись, в родительском
>процессе закрыли, в дочернем общаемся с клиентом. Но есть интересный момент
>с другими файлами, которые могли наоткрываться в родительском процессе, особенно в
>других потоках. Они останутся в дочернем. Вроде как не особо и
>мешает это, но всё же лучше бы их тоже закрывать.

Не зря :) автор же написал:
>1. Вести учет открытых файловых дескрипторов по всему приложению я, разумеется, не
>собираюсь, по этой же причине никаких FD_CLOEXEC.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

5. "Треды + fork"  
Сообщение от Petr (??) on 27-Мрт-09, 15:51 
>Не зря :) автор же написал:
>>1. Вести учет открытых файловых дескрипторов по всему приложению я, разумеется, не
>>собираюсь, по этой же причине никаких FD_CLOEXEC.

Вы что же, не согласны, что это угрёбищное решение? Хотя бы потому, что в проекте используются закрытые библитеки, которые файлы открывают, а вот впихнуть в них fcntl - звиняйте. Поэтому я просил решение, а не костыль.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

7. "Треды + fork"  
Сообщение от vic (??) on 27-Мрт-09, 16:29 
>>Не зря :) автор же написал:
>>>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, но он может быть не везде.

Прием никаким образом не спасает от неопределенного поведения модулей кода которые зависят от закрытых, в обход этих модулей, дескрипторов.

Кросплатформенного решения в данном случае не может быть, слишком разные платформы, тем более никому не ясен ваш список ОС :)

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

8. "Треды + fork"  
Сообщение от Petr (??) on 27-Мрт-09, 17:39 
>Не следить за дескрипторами это и есть 'угрёбищное' решение.
>
>Использовать для всех управляемых дескрипторов флаг 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.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

4. "Треды + fork"  
Сообщение от Petr (??) on 27-Мрт-09, 15:43 
>1. Есть shutdown()
>2. п. 1 не спасёт от небходимости закрывать дескриптор в parent ---
>иначе потекут дескрипторы, а это ограниченный ресурс.

shutdown не то. Нужно _закрыть_ в ребенке все, кроме 0,1,2. TCP соединение обрабатывается  в родителе, в котором все, что нужно, закрывается.

>3. Аффтору убить себя ап стену.

Детский сад...

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

6. "Треды + fork"  
Сообщение от const86 (ok) on 27-Мрт-09, 16:09 
> Нужно _закрыть_ в ребенке все, кроме 0,1,2.

Можно посмотреть свой RLIMIT_NOFILE и пробежаться в цикле, всё поcloseить.
Смутно припоминается, что это как-то вроде можно побыстрее сделать, но не могу вспомнить.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

9. "Треды + fork"  
Сообщение от svn (??) on 27-Мрт-09, 23:08 
>shutdown не то. Нужно _закрыть_ в ребенке все, кроме 0,1,2.

Закрой в себе сначала всё плохое и ненужное, а потом делай детей.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

10. "Треды + fork"  
Сообщение от Аноним (??) on 29-Мрт-09, 17:35 
>Закрой в себе сначала всё плохое и ненужное, а потом делай детей.

Универсальный ответ. Напиши его во все темы на этом форуме и застрелись, идиот :))

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Оцените тред (1=ужас, 5=супер)? [ 1 | 2 | 3 | 4 | 5 ] [Рекомендовать для помещения в FAQ]




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру