Форум: "Сети";
Текущий архив: 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.004 c