Сигнализация всех активных тем (Windows) - PullRequest
0 голосов
/ 05 августа 2011

Я столкнулся с проблемой дизайна, касающейся синхронизации потоков в C ++, Windows.

Я пишу серверное приложение, которое запускает один прослушивающий поток, который должен оставаться активным все время, пока сервер работает.Когда прослушивающий поток получает запрос connect , он открывает сокет CONTROL и запускает новый поток control .Этот поток используется для отправки управляющих данных между сервером и клиентом, инициализации сервера и всего фонового программного обеспечения для конкретных данных клиента и запуска обработки данных.

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

Когда клиент разорвет соединениенеблагоразумно, завершив приложение без вызова функции, которая отправляет серверное сообщение, чтобы закрыть соединение, вот что должно произойти:

  • Любой из выполняющихся потоков может обнаружить это событие.Они получат какую-то ошибку (WSAECONNRESET) при отправке или получении через сокет DATA / CONTROL, а затем должны сообщить всем другим потокам, что они должны прекратить выполнение (кроме потока прослушивания сервера).

Какой самый естественный способ добиться такого поведения?

(я использую winsock (winsock2.h) для работы в сети и стандартный api-интерфейс windows (windows.h) для многопоточности)

Ответы [ 2 ]

0 голосов
/ 05 августа 2011

Вы можете использовать функцию WSAEventSelect (), чтобы связать объект события с сокетом и создать один объект события для ваших событий, а затем использовать эти объекты события в функции WaitForMultipleObjects (), чтобы ваш поток мог ожидать события сокета и ваши пользовательские события.

0 голосов
/ 05 августа 2011

Если вы пишете многопоточный сервер winsock, вы должны изучить порты завершения ввода-вывода. Использование порта завершения ввода-вывода является наиболее масштабируемым способом написания сетевого сервиса на платформе Windows.

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

В любом случае вы будете использовать WSARecv . Когда WSARecv возвращает ненулевое значение, вызовите WSAGetLastError () . Если у вас нет WSA_IO_PENDING , включите ошибку и найдите код ошибки winsock , который вас интересует.

Код ошибки winsock WSA_OPERATION_ABORTED указывает, что сокет закрыт, хотя есть и другие (например, WSAECONNABORTED).

Предлагает хороший текст по этому вопросу (например, Windows через C / C ++).

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