Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.04.10;
Скачать: CL | DM;

Вниз

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

 
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;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.011 c
15-1293026590
картман
2010-12-22 17:03
2011.04.10
db comparer


15-1293012299
TUser
2010-12-22 13:04
2011.04.10
Итак, военные хакеры вероятного противника ...


15-1293014298
Медвежонок ХМЛ
2010-12-22 13:38
2011.04.10
Взлетит или не взлетит?


6-1236235577
DrZloDey
2009-03-05 09:46
2011.04.10
Перенаправление портов


15-1293461610
ANB
2010-12-27 17:53
2011.04.10
Вместо наведения порядка - возврат к прописке ?