The OpenNET Project / Index page

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

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

"можно ли определить занят сокет или нет?"  
Сообщение от L email(??) on 22-Янв-07, 20:41 
На linux работает сервер, который создает разные threads для каждого клиента. И время от времени при большой загрузке получается такая ситуация:
сокет в одной из thread получает ошибку сети (например timeout или "socket closed by peer"),
  деструктор закрывает его close-ом,
    на верхнем уровне происходит откат для этой thread, который занимает некоторое время.
И если в этот самый момент появляется другая thread, то система может дать ей тот же самый дескриптор сокета, и он начинает работать.
Но
      первая thread в процессе отката вызывает "delete <дескриптор сокета>", потому что он был открыт по new <class сокет>, и получается что удаляет уже работающий сокет, да еще и не в своей области памяти, catch такое не ловит, и сервер падает.

Скажите пожалуйста, как определить, занят ли системой конкретный сокет (или адрес памяти), причем какой-то другой thread, а не текущей?

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

 Оглавление

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


1. "можно ли определить занят сокет или нет?"  
Сообщение от BigHo on 22-Янв-07, 21:03 
>Скажите пожалуйста, как определить, занят ли системой конкретный сокет (или адрес памяти),
>причем какой-то другой thread, а не текущей?

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

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

Если получится, что я чего-то недопонимаю, то кусок кода это может исправить :)

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

3. "можно ли определить занят сокет или нет?"  
Сообщение от L email(??) on 22-Янв-07, 21:24 
>В данном случае как раз никакой проблемы нет. Для того, чтобы этот
>же номер дескриптора смог быть использован еще раз (accept ?), его
>обязан высвободить вызов close. Поэтому этот вызов надо задвинуть в конец
>деструктора. Он должен выполниться только после того, как все свзяанные структуры
>по этому потоку и сокету будут высвобождены (т.е. не останется ни
>одного указателя извне). Это конечено в идеале и тут могут быть
>ньюансы.

Да, у меня тоже пока только эта мысль, но это может оказаться очень громоздко, слишком длинная цепочка наследуемых классов

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

4. "можно ли определить занят сокет или нет?"  
Сообщение от BigHo on 22-Янв-07, 21:41 
>Да, у меня тоже пока только эта мысль, но это может оказаться
>очень громоздко, слишком длинная цепочка наследуемых классов

Т.е. очень хочется хака ? :) Ну тогда наабум:
- убрать close из деструктора, либо заменить на dup2(_dev_null_fd, closefd), если должен быть валидным;
- создать в массиве размером getdtablesize() пометку о том, что этот дескриптор должен быть закрыт после всей череды вызова деструктора.

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

5. "можно ли определить занят сокет или нет?"  
Сообщение от L email(??) on 22-Янв-07, 22:26 
>- убрать close из деструктора, либо заменить на dup2(_dev_null_fd, closefd), если должен быть валидным;
Точно, так и придется убирать close

>- создать в массиве размером getdtablesize() пометку о том, что этот дескриптор
>должен быть закрыт после всей череды вызова деструктора.
По сути это то же, что создавать при открытии новой thread список открытых сокетов и по завершении thread делать close для них или что-то другое?

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

6. "можно ли определить занят сокет или нет?"  
Сообщение от Michelnok (ok) on 22-Янв-07, 22:43 
>По сути это то же, что создавать при открытии новой thread список
>открытых сокетов и по завершении thread делать close для них или
>что-то другое?

Не занимайся ерундой. Нечего делать close два раза одному и тому же дескриптору, после первого close он недействителен. На крайняк:

if(sock!=-1) {
  close(sock);
  sock=-1;
}

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

7. "можно ли определить занят сокет или нет?"  
Сообщение от L email(??) on 22-Янв-07, 22:57 
>Не занимайся ерундой. Нечего делать close два раза одному и тому же
>дескриптору, после первого close он недействителен. На крайняк:

В том-то и дело, что во время [delete socket_descriptor] неизвестно, было уже
[close(<socket descriptor>)] или нет. А если в одной thread будет не один сокет, а несколько (например сервер по запросу клиента сам запрашивает у другого сервера и потом передает клиенту), то эти навороты с sock=-1 приведут к куче глобальных переменных, что уже само по себе плохо.

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

8. "можно ли определить занят сокет или нет?"  
Сообщение от Michelnok (ok) on 23-Янв-07, 00:30 
>эти навороты с sock=-1 приведут к куче глобальных переменных, что уже само по себе плохо

ЗАЧЕМ ТУТ ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ?


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

9. "можно ли определить занят сокет или нет?"  
Сообщение от L email(??) on 23-Янв-07, 00:54 
Затем что в данном случае (читай с самого начала) сокет оказывается принадлежащим в некоторый момент времени двум РАЗНЫМ threads

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

10. "можно ли определить занят сокет или нет?"  
Сообщение от Michelnok (ok) on 23-Янв-07, 01:48 
>Затем что в данном случае (читай с самого начала) сокет оказывается принадлежащим
>в некоторый момент времени двум РАЗНЫМ threads

Нда...

class Socket
{
public:

  Socket()
  {
    sock=socket(...);
  }

  ~Socket()
  {
    close();
  }

  void close()
  {
    if(sock!=-1) {
      close(sock);
      sock=-1;
      }
  }

protected:
  int sock;
};

Где-то при возникновении ошибки:
  pSocket->close(); // если уж так очень хочется и не терпится должаться деструктора

Где-то позже:
  delete pSocket;

Ну, если и на этот раз непонятно, тогда я пас.

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

2. "можно ли определить занят сокет или нет?"  
Сообщение от Andrew email(??) on 22-Янв-07, 21:14 
>На linux работает сервер, который создает разные threads для каждого клиента. И
>время от времени при большой загрузке получается такая ситуация:
>сокет в одной из thread получает ошибку сети (например timeout или "socket
>closed by peer"),
>  деструктор закрывает его close-ом,
>    на верхнем уровне происходит откат для этой thread,
>который занимает некоторое время.
>И если в этот самый момент появляется другая thread, то система может
>дать ей тот же самый дескриптор сокета, и он начинает работать.
>
>Но
>      первая thread в процессе отката вызывает "delete <дескриптор сокета>", потому что он был открыт по new <class сокет>, и получается что удаляет уже работающий сокет, да еще и не в своей области памяти, catch такое не ловит, и сервер падает.
>
>Скажите пожалуйста, как определить, занят ли системой конкретный сокет (или адрес памяти),
>причем какой-то другой thread, а не текущей?

перечитывай свой вопрос пока не поймешь в чем его глупость.
подсказка: если так и не поймешь - спрашивай.

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

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

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




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

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