Итак, я искал перекрывающийся ввод-вывод для сокетов для серверного приложения, которое я создаю, и я продолжаю видеть комментарии людей, говорящих «никогда не используйте hEvent
«или» порты завершения ввода-вывода будут быстрее «и т. д., но никто никогда не говорит, ПОЧЕМУ не использовать hEvent
и никто никогда не предоставляет реальных данных или чисел о том, что порты завершения быстрее или быстрее. hEvent
с WaitForMultipleObjects()
лучше вписывается в мое приложение, поэтому, если разница в скорости незначительна, я склонен ее использовать, но я не хочу брать на себя это без каких-либо реальных данных, говорящих мне о том, какую большую жертву я там принесу. Я гуглил, гуглял и гуглял и не могу найти ни тестов, ни статей, ни НИЧЕГО, сравнивая две стратегии, кроме нескольких ответов StackOverflow, говорящих «не используйте эту» без объяснения причин.
Может ли кто-нибудь предоставить мне некоторую реальную информацию или цифры о практической, реальной разнице между использованием hEvent
а доработка портов?
Этот ответ исходит от Гарри Джонстона в качестве комментария к этому вопросу, и после небольшого поиска я нашел еще несколько деталей, которые делают WaitForMultipleObjects
страшная вещь.
Максимальное количество объектов, которое вы можете подождать, составляет 64. Уже одно это делает масштабируемость подхода WFMO практически не существующей. Но, посмотрев дальше, я нашел эту тему: https://groups.google.com/forum/#!topic/comp.os.ms-windows.programmer.win32/okwnsYetF6g
В терминах NT, чтобы ввести ожидание,
Блок ожидания должен быть выделен для каждого объекта, и каждый блок ожидания
поставлен в очередь на ожидаемый объект, а затем перекрестно связан с
нить. Когда любой из этих объектов сигнализирует все эти блоки ожидания
должны быть выведены из очереди, не связаны и освобождены обратно в пул. Все это
происходит в DISPATCH_LEVEL и все, кроме выделения пула и свободных
происходит с удерживаемой диспетчерской спин-блокировкой.(WFMO с fAll == ИСТИНА еще дороже. Каждый раз, когда
объекты сигнализируются, все остальные должны быть проверены. Это все
бывает, как вы уже догадались, при DISPATCH_LEVEL с спин-блокировкой диспетчера
Ручной.)
Такая спин-блокировка на уровне диспетчера предотвращает вытеснение и временную нарезку потоков во всей системе, даже с несколькими ядрами. Это ужасно и хорошая причина никогда не использовать WFMO
на что угодно, если вы ожидаете более 3 объектов (поток имеет 3 заранее выделенных блока ожидания и может избежать этого, если вы ожидаете 3 или меньше).
Для максимальной производительности вы должны использовать порты завершения ввода-вывода. Количество розеток не ограничено. Все остальные подобные API будут обслуживать только 1024 сокета, и производительность будет быстро падать вместе с более высоким, чем требуется, использованием ЦП.
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365198(v=vs.85).aspx
Вы также можете проверить эту замечательную презентацию об асинхронном вводе-выводе, которая, я думаю, является обязательной для тех, кто задумывается о написании средних и крупных клиент-серверных приложений.
История времени: асинхронный C ++ — Стивен Симпсон [ACCU 2017] https://www.youtube.com/watch?v=Z8tbjyZFAVQ
В этой презентации вы найдете полное описание и сравнение доступных технологий, а также результаты тестов. Стоит потратить время.
Ограничение WaitForMultipleObjects () до 64 дескрипторов делает его непрактичным для обработки чего-либо, включающего более нескольких потоков ввода-вывода.