2012-05-17 3 views
0

У меня есть приложение IOCP, в котором хранится буфер на 64 кбайта на один сокет. Он использует много оперативной памяти, одновременно обрабатывая тысячи сокетов. Вместо этого я хочу переключиться на модель, где у меня есть 64kb-буфер для каждого потока iocp-потоков (например, я могу сделать это в epoll и kqueue). Для этого мне нужно, чтобы мой порт завершения мог получать уведомления без копирования байтов в предоставленный WSABUF, и после уведомления просто вызывайте async WSARecvFrom (без предоставления перекрытой структуры, я использую udp для тестов), пока не получаю WSAEWOULDBLOCK. Я прочитал, что следующая техника может быть достигнута, если я предоставляю пустой WSABUF (buf = NULL, len = 0) для вызова WSARecvFrom с перекрывающейся структурой. Но это не работает: IOCP никогда не «просыпается», поскольку буфер слишком мал.IOCP: уведомления без байта копия

Есть ли другие способы сделать такой сценарий возможным?

ответ

2

Это хорошо работает для TCP, и это хороший способ избежать ограничения «заблокированных страниц», что было большой проблемой для более ранних версий Windows, но, похоже, сейчас это проблема. Он должен отлично работать для вашей ситуации.

У меня есть пример кода кода IOCP, который может быть downloaded from here, и это поддерживает «чтение с нулевым байтом» и последующие асинхронные чтения (то есть только выдано перекрываемое чтение с буфером после завершения чтения с нулевым байтовым буфером) , мой последний код поддерживает как синхронизацию, так и асинхронные чтения после завершения чтения нулевого байта.

Обратите внимание, что если вы имеете дело с TCP, вы указываете, что используете UDP «для тестов», тогда вы можете достичь «единого буфера», выпустив только одно перекрываемое чтение для каждого соединения. Как только это чтение будет завершено, вы сможете справиться с этим, прежде чем выпустить новое перекрываемое чтение с использованием того же буфера ...

«Нулевое чтение в байтах» по-прежнему полезно, если вам нужно иметь дело со многими тысячами параллельных подключений, где соединения отправлять данные нечасто, поскольку это уменьшает количество заблокированных страниц за один раз до минимума. Использование этого для сокращения использования памяти потребует, чтобы вы только распределяли буфер для соединения после завершения «чтения с нулевым байтом».

+0

Благодарим за сообщение. Но как насчет UDP? Мое приложение обрабатывает соединения TCP и UDP, и я хочу иметь одну архитектуру. Возможно ли для UDP? – user1266334

+0

Я не пробовал с UDP. Я ожидаю, что ввод-вывод завершится ошибкой «больше данных», и вы не сможете получить остальную дейтаграмму. Вы действительно ожидаете UDP датаграммы 64K? Я предполагаю, что вы не проходите через какие-либо маршрутизаторы, и это прямое локальное соединение? –

+0

I/O никогда не завершает чтение «нулевого байта». Если я поставлю 1-байтовый буфер, он также никогда не будет завершен. Однако, если я помещаю буфер 64k, он отлично работает. Максимальный размер дейтаграммы UDP - 64k, поэтому да, я ожидаю такие датаграммы. Я делаю тесты на localhost, но мое приложение, конечно, будет работать в Интернете. – user1266334

Смежные вопросы