Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2011.04.10;
Скачать: [xml.tar.bz2];

Вниз

Зависание над чтением сокета   Найти похожие ветки 

 
It's not me   (2009-03-04 19:51) [0]

Есть поток, который занимается постоянным чтением из сокета через RecvFrom. В любой момент может быть приказ о завершении работы (приложение завершается).

Сигналом к тому, что пора завершаться является выставление у потока (в виде класса от TThread) свойства Terminated в true и дерганье определенного эвента, допустим WorkEvent;

Не могу понять, как элегантно отслеживать данные ситуации.

- если впрямую использовать RecvFrom, то при отсутствии данных поток зависнет в блокировке. Соответственно, так и будет висеть и никакими сигналами его не разбудить. Плохо.

- есть такая функция select, ее можно использовать, но это только частично решает проблему. То есть, можно делать select на определенный TimeOut. После отвисания проверять свойство Terminated и опять select.
Но тут проблема в том, чтобы выбрать оптимальный TimeOut. Чем он меньше - тем больше загрузка процессора на перепроверки, входы / выходы в синхронизацию и так далее. Чем больше TimeOut - тем медленнее средняя реакция потока на уведомления о завершении потока.

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

Подскажите что делать, а скорее всего ответ просто в указании на соответствующий WinSock функции, которые позволяют создать такой объект.


 
Сергей М. ©   (2009-03-04 20:04) [1]


> соответствующий WinSock функции, которые позволяют создать
> такой объект


Ты не поверишь - это хорошо известная и всенароднолюбимая ф-ция WinAPI CreateEvent()

И используется этот ивент в ф-ции WSAEventSelect


> в идеале я вижу это как вызов: WaitForMultipleObject от
> двух объектов


Далеко не единственное и не всегда идеальное решение.

Есть еще и MsgWaitForMultipleObjects. В комплексе с WSAEnumNetworkEvents позволяет преодолеть все мыслимые "неудобства".


> если впрямую использовать RecvFrom, то при отсутствии данных
> поток зависнет в блокировке


Ничто не мешает закрыть хэндл гнезда из другого потока - блокирующая ф-ция тут же "отвиснет" с соответствующим ожидаемым кодом отказа.

Это весьма распространенный и вполне коррекный способ прерывания блокирующей операции ввода-вывода.


 
Сергей М. ©   (2009-03-04 20:09) [2]

Собссно говоря, ф-ция такая имеется - WSACreateEvent.
Но она не более чем раппер для CreateEvent.


 
Сергей М. ©   (2009-03-04 20:16) [3]


> можно делать select на определенный TimeOut


В Indy именно так и реализовано. И никто не жалуется. А робкие жалобы перекрываются железным аргументом - кроссплатформенностью такого решения.


 
Slym ©   (2009-03-05 04:46) [4]

Закрыть сокет и Recvы отвалятся
It"s not me   (04.03.09 19:51)
Сигналом к тому, что пора завершаться является выставление у потока (в виде класса от TThread) свойства Terminated в true

и потом Socket.Close;


 
It's not me   (2009-03-05 11:53) [5]


> Ничто не мешает закрыть хэндл гнезда из другого потока -
>  блокирующая ф-ция тут же "отвиснет" с соответствующим ожидаемым
> кодом отказа.
>
> Это весьма распространенный и вполне коррекный способ прерывания
> блокирующей операции ввода-вывода

корректный?! То есть, это вполне документировано? Ну тогда так и сделаю, спасибо большое!


 
Сергей М. ©   (2009-03-05 12:45) [6]


> It"s not me   (05.03.09 11:53) [5]
>
>


> так и сделаю


Тогда возникунут проблемы с совместимостью решения с другими платформами.
При неблок.режиме и select-мультиплексировании c таймаутом такавя проблема не возникнет.


 
It's not me   (2009-03-05 13:23) [7]


> Тогда возникунут проблемы с совместимостью решения с другими
> платформами

с линуксом что ли? ))))
Я даже не планирую делать кроссплатформенную систему. Там несовместимостей будет как грязи )))


 
Сергей М. ©   (2009-03-05 13:28) [8]


> даже не планирую делать кроссплатформенную систему


Тогда есть ненулевой резон задействовать возможности асинхронного режима, характерные именно для WSP - семейство WSAxxx-ф-ций, в частности WSA[Async/Event]Select, о которых ты заикнулся в самом начале.


 
It's not me   (2009-03-05 13:56) [9]

А нафига? Так закрытие сокета из другого потока, когда первичный поток висит на RecvFrom нормально или все таки не очень нормально?


 
Сергей М. ©   (2009-03-05 14:24) [10]

MS это не комментирует.

Но судя по фактической успешности такого решения для Winsock 2 (никакие проблемы при этом не наблюдаются) оно имеет право на жизнь.



Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2011.04.10;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.47 MB
Время: 0.005 c
6-1233550485
vann
2009-02-02 07:54
2011.04.10
Как задать таймаут при определении имени хоста?


2-1294871283
Ghost del vonte
2011-01-13 01:28
2011.04.10
Проблема при удалении последней вкладки на TabSet


9-1188239972
Woriors
2007-08-27 22:39
2011.04.10
Как правильно делать игры


2-1294736710
worldmen
2011-01-11 12:05
2011.04.10
Удаление заголовка окна


9-1186778469
Gari
2007-08-11 00:41
2011.04.10
Проигрование звука в игре





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский