отправить через IP сразу в другой теме - PullRequest
1 голос
/ 09 февраля 2011

Это, вероятно, невозможно, но я все равно спрошу.У меня есть многопоточная программа (сервер), которая получает запрос в потоке, выделенном для IP-коммуникаций, а затем передает его рабочим потокам для выполнения работы, затем я должен отправить ответ обратно с ответами клиенту и отправить его, когдаэто фактически закончено, с минимальной задержкой насколько возможно.В настоящее время я использую шаблон «потребитель / производитель» и помещаю ответы в очередь, чтобы поток IP мог снять и отправить обратно моему клиенту.Это, однако, не дает мне никакой гарантии, КОГДА это произойдет, так как поток IP может не планироваться в ближайшее время, я не могу знать.Это заставляет моего клиента, который блокирует этот вызов, думать, что запрос не выполнен, что, очевидно, не имеет значения.

Из-за того, что я не могу внести изменения в клиент, мне нужно решить эту проблему со своей стороны, проблема, с которой я сталкиваюсь, заключается в том, что я не хочу начинать делиться своим объектом IP(в настоящее время только в 1 потоке) с рабочими потоками, так как тогда все становится слишком сложным.Я задавался вопросом, есть ли какой-нибудь способ, которым я могу использовать механизмы синхронизации потока, чтобы гарантировать, что в тот момент, когда мой рабочий поток завершит свою работу, поток IP выполнит мою отправку ответа обратно клиенту?

Будут ли ручные / автосбросные события делать это для меня или они не гарантируют немедленное пробуждение потока?

Ответы [ 2 ]

2 голосов
/ 09 февраля 2011

Если вам нужно, чтобы оно было отправлено немедленно , ваш лучший выбор - прикусить пулю и начать делиться объектом подключения. Конечно, заблокируйте его, прежде чем обращаться к нему, и обязательно подумайте о том, что вы будете делать, если буфер отправки уже заполнен (поток соединения должен будет иметь дело с отправкой части сообщения, которая не подходит в первый раз или рабочий поток будет заблокирован, пока клиент не примет часть отправленных вами данных). Это не может быть слишком сложно, если ваши клиенты выполняют только один запрос за раз; в этом случае вы можете просто передать владение клиентским объектом рабочему потоку, когда он начнет обработку, и вернуть его, когда закончите.

Другой вариант - использование потоков в реальном времени. Детали будут различаться в разных операционных системах, но в большинстве случаев, если ваш поток имеет достаточно высокий приоритет, он будет запланирован немедленно, как только он будет готов к работе, и будет вытеснять все другие потоки с более низким приоритетом до тех пор, пока не будет выполнено. В Linux это можно сделать, например, с помощью класса приоритета SCHED_RR . Тем не менее, это может негативно повлиять на производительность во многих случаях; а также сбой системы, если ваш поток попадает в бесконечный цикл. Также обычно требуются права администратора для использования этих классов планирования.

Тем не менее, если планирование занимает достаточно много времени, чтобы время ожидания клиента истекло, у вас могут возникнуть другие проблемы с нагрузкой. Вы также должны указать, насколько быстрым должен быть ответ - нет конца, что вы можете сделать, если хотите ускорить ответ, но наступит момент, когда это уже не имеет значения ( нужен ответ в десятках мс (однозначные мс, сотни микросекунд, однозначные микросекунды?).

2 голосов
/ 09 февраля 2011

Не существует механизма синхронизации, который немедленно разбудит поток. Когда сигнализируется механизм синхронизации, которого ожидает поток, поток помещается в готовую очередь для своего класса приоритета. Там его можно голодать в течение нескольких секунд, прежде чем он запланирован (в Windows есть механизмы, которые справляются с голоданием в течение 3-4 секунд).

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...