Блокирующие сокеты + потоки

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Блокирующие сокеты + потоки

Сообщение VirtUX » 12.08.2013 13:17:56

Использую TUDPBlockSocket для общения клиента и сервера.
Клиентов более 100.
В будущем планируется организовать суб-сервера группирующие и обслуживающие подгруппы клиентов, а так же сбрасывающие итоги на мастер-сервер.
На клиенте все просто:
- отправили запрос;
- получили квитанцию о доставке запроса;
- перешли в режим ожидания ответа;
- получили ответ.
На сервере:
Планирую
- в отдельном потоке читать из сокета (тут же отправив квитанцию о получении запроса), и через критическую секцию (КС_БВЗ) сохранять в буфер входящих запросов;
- в другом отдельном потоке через КС_БВЗ читаем запросы, и для каждого отдельного запроса порождаем поток обработчик;
- поток обработчик результат сохраняет через критическую секцию (КС_БГО) в буфер готовых ответов;
- в третьем отдельном потоке через КС_БГО читаются ответы и через сокет отправляются клиенту.

Что мне хотелось бы узнать:
Как правильно организовать доступ к единственному сокету из двух потоков, которые: один читает из него, другой отправляет ответы через него?
Как мне это видится:
Через критическую секцию организовать доступ к сокету. Но если я в один момент отправляю ответ, и на сокет пришел запрос - никакого казуса не выйдет?
P.S. Если можно, то объясните подробно: что конкретно блокируется и в какой момент при работе с сокетом? То, что основной процесс переходит в ожидание - это понятно, но в моем случае как это выглядит?
Спасибо!
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 880
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: Блокирующие сокеты + потоки

Сообщение hinst » 12.08.2013 13:45:58

TUDPBlockSocket
Это в какой библиотеке такой класс?
"Блокирующие сокеты" это когда при вызове метода Send, например, управление вызывающей процедуре передаётся только после того, как данные будут отправлены. "Неблокирующие сокеты" в таком случае это такие, которые при вызове метода Send, например, возвращают управление сразу, а отправлять данные начинают в каком-нибудь отдельном потоке или ещё как-нибудь, но часто это реализовано именно так, что "неблокирующие сокеты" создают ещё один поток (или много?), так что вы сейчас контроллите руками то, что они делают "сами". Короче если я ещё не сошёл с ума, слово "блокирующие" сокеты означает то, что они не возвращают управление вызывающей процедуре пока не отправят или не примут данные, смотря какой метод вызвали, больше в них ничего такого не блокируется
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Re: Блокирующие сокеты + потоки

Сообщение VirtUX » 12.08.2013 13:51:37

спасибо!
TUDPBlockSocket - это класс в модуле blcksock из пакета synapse. Использую, т.к. там много чего реализовано часто используемого, и... вродебы, не глючит :)
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 880
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: Блокирующие сокеты + потоки

Сообщение hinst » 12.08.2013 14:46:34

VirtUX писал(а): Как правильно организовать доступ к единственному сокету из двух потоков, которые: один читает из него, другой отправляет ответы через него?
Как мне это видится:
Через критическую секцию организовать доступ к сокету. Но если я в один момент отправляю ответ, и на сокет пришел запрос - никакого казуса не выйдет?

Чтение и запись не должны зависеть друг от друга; если сделать одну критическую секцию и на чтение, и на запись, то получится плохо: пока отправляешь данные, не сможешь читать входящие данные (казуса, скорее всего, не выйдет, просто будет тормозить сильнее, чем могло бы), так что, критическая секция в этом случае, скорее всего, не нужна.
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Re: Блокирующие сокеты + потоки

Сообщение VirtUX » 12.08.2013 15:50:36

Меня берут сомнения вот в чем: если во время незавершенного чтения из сокета, ОС отдаст процессорное время потоку, который начнет отправлять через сокет ответ (или наоборот), то недоотправленные или недополученные данные в следующем переключении очереди потоков доотправятся/дополучатся? Мне интересно: ОС блокирующему сокету даст завершить чтение или отправку данных? Или выделенное процессорное время закончившись оборвет передачу/чтение?
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 880
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: Блокирующие сокеты + потоки

Сообщение SeZuka » 13.08.2013 08:45:17

VirtUX писал(а):Или выделенное процессорное время закончившись оборвет передачу/чтение?

Если бы так работала ОС, то мы бы никогда не увидели нормального изображения на экране и не услышали бы звуков из колонок и не было бы связи между компьютерами.
Вы бы лучше подумали о другой проблеме, ваша программа может повиснуть, из-за ожидания блокирующим сокетом данных, которые где-то затерялись в сети.
SeZuka
постоялец
 
Сообщения: 209
Зарегистрирован: 05.09.2012 14:58:05

Re: Блокирующие сокеты + потоки

Сообщение VirtUX » 13.08.2013 14:07:55

SeZuka писал(а):программа может повиснуть, из-за ожидания блокирующим сокетом данных, которые где-то затерялись в сети.

для этого есть тайминги: как в процедурах модуля blcksock, так и в моих вызывающих процедурах. Т.ч. проблемы в этом нет, работает отлично.
SeZuka писал(а):Если бы так работала ОС, то мы бы никогда не увидели нормального изображения на экране и не услышали бы звуков из колонок и не было бы связи между компьютерами.

Спасибо, - утешили :) Значит долой критику на сокет.
Еще раз всем спасибо за разъяснения!
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 880
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: Блокирующие сокеты + потоки

Сообщение Kemet » 13.08.2013 16:01:22

Где-то была переводная статья (возможно на хабре), что вместо организации конкуренции за сокеты и разгребания проблем, лучше открывать столько сокетов, сколько нужно для разных потоков. Хотя в статье речь больше шла о производительности, тем не менее, думаю, в случае ТС такой подход также подойдёт.
Kemet
постоялец
 
Сообщения: 241
Зарегистрирован: 10.02.2010 19:28:32
Откуда: Временно оккупированная территория

Re: Блокирующие сокеты + потоки

Сообщение VirtUX » 13.08.2013 18:16:54

Kemet писал(а):открывать столько сокетов, сколько нужно для разных потоков

тогда придется пробрасывать кучу портов на роутере. Каждому клиенту привязываться к своему порту, и прочие проблемы. Сокет должен быть один для всех клинтов. Иначе головняка будет.......
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 880
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: Блокирующие сокеты + потоки

Сообщение GrayEddy » 13.08.2013 23:37:23

Kemet, возможно, имел в виду, что на одно новое соединение создается новый тред. Но этот способ хорош для асинхронного сокета.
GrayEddy
постоялец
 
Сообщения: 375
Зарегистрирован: 06.05.2005 09:37:56

Re: Блокирующие сокеты + потоки

Сообщение VirtUX » 14.08.2013 11:11:48

GrayEddy писал(а):на одно новое соединение создается новый тред

в принципе я так и реализую:
VirtUX писал(а):в другом отдельном потоке через КС_БВЗ читаем запросы, и для каждого отдельного запроса порождаем поток обработчик;
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 880
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

Рейтинг@Mail.ru