2015-05-28 9 views
2

Я пытаюсь понять, почему используется IOCP. Я думаю, по двум причинам:Почему используется IOCP?

  • Поскольку WSARecv() не будет блокировать, то я могу справиться с 1000s клиентов без необходимости создавать новый поток для каждого клиента (также существует ограничение на сколько потоков вы можете создать , и поэтому количество клиентов, с которыми вы можете справиться, будет ограничено).
  • С WSASend() не будет блокироваться, а затем, когда я хочу отправить большой файл, мне не нужно создавать новый поток для его отправки (если я не создавал новый поток, тогда поток пользовательского интерфейса будет блокироваться, конечно) ,

Какие еще причины для использования IOCP?

+2

Уверен, что нет нитей, ожидающих завершения ввода-вывода. Это не масштабируется, потоки слишком дороги. –

ответ

1

IOCP обладает теми преимуществами, которые вы упомянули, но это не относится к IOCP. Я не знаком с API-интерфейсами родных сокетов, но некоторые API-интерфейсы Win32 имеют «перекрывающиеся IO», которые являются асинхронными, но не требуют IOCP.

Другим преимуществом является то, что с IOCP количество обрабатываемых потоков запросов (типа) оптимизировано ядром. Ядро известно обо всех блокированиях, которые выполняют запросы обслуживающего потока, и он будет следить за тем, чтобы было достаточно и не больше потоков, которые были разблокированы в любое время, чтобы процессор был хорошо использован. В идеале вы бы никогда не блокировали, и было бы столько потоков, сколько есть ядер (при условии 100% нагрузки). Это было бы очень эффективно.

IOCP также помогает уменьшить переключение контекста, потому что вместо перехода на другой поток для обработки результатов ввода-вывода существующий поток, который занят, уже просто вызывает GetQueuedCompletionStatus.

GetQueuedCompletionStatusEx может использоваться для уменьшения количества переходов в ядро, поскольку вы можете удалить несколько IO за один вызов.

+1

На самом деле ** все ** I/O в Windows является асинхронным, насколько это касается ядра. Синхронные версии предоставляются в качестве удобства. Дополнительная информация доступна в [Я знаю, что для перекрываемого дескриптора файла требуется lpOverlapped, но почему он (иногда) работает, если я его опускаю?] (Http://blogs.msdn.com/b/oldnewthing/archive/2012/ 04/11/10292442.aspx) – IInspectable

1

Кроме того, он сокращает количество циклов копирования и защиты кольцевых копий. Вместо того, чтобы ядро ​​должно было копировать данные из буферов сетевого стека в буфер пространства пользователя при запросе вызова recv(), буферы пользовательского пространства поставляются WSARecv(), и стек может затем загружать их непосредственно в пространстве ядра.