Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
чтиво_ч2.doc
Скачиваний:
8
Добавлен:
15.11.2019
Размер:
284.67 Кб
Скачать

Использование потоков

Перед тем, как начать рассказывать про перекрытые модели хотелось бы объяснить некоторые детали использования потоков. Если принять во внимание понятие потока, то некоторые из объясненных моделей могут показывать различное поведение. Например, блокирующие socket’ы в однопоточных приложениях заблокируют все приложение. Однако, когда блокирующие socket’ы используются в многопоточных приложениях, причем в разных потоках, то главный поток продолжает выполняться, в то время как вспомогательный поток блокирован. Для серверов с очень малой пропускной способностью (около 10-50 соединений) легко и целесообразно осуществить select модель в однопоточном соединении для каждого клиента. Каждый запущенный поток связан с определенным соединением.

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

То же самое справедливо и для других моделей, хотя некоторые из них лучше сочетать с потоками, а другие нет. Например WSAAsyncSelect использует оконные сообщения. Вы можете использовать потоки, но, так или иначе, Вам придется передать полученные сообщения в рабочий поток. Более легкой моделью для использования является WSAEventSelect: так как потоки могут ожидать события (даже многократные), то уведомления о этих событиях напрямую действуют с потоком (Вам не надо использовать два потока как в случае с WSAAsyncSelect). Так же могут быть использованы чисто блокирующие socket’ы, но в таком случае трудно контролировать поток, т.к. его блокирует WinSock функция (аналогичная проблема наблюдается и у select-модели). При использовании событий Вы можете создавать пользовательские события (не связанные с WinSock) и использовать их для уведомления потоку о том, чего не требуется делать с socket’ом.

Как Вы могли заметить, потоки являются очень мощным инструментом и могут радикально изменить принцип работы той или иной модели ввода/вывода. Большинству серверов необходимо обрабатывать множественные запросы одновременно, поэтому использование потоков является отличным вариантом для решения этой проблемы. Пока что данной информации о потоках нам хватит для освоения перекрытого ввода/вывода.

Введение в перекрытый ввод/вывод

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

В рассмотренных ранее моделях посылались некоторые уведомления (такие как «данные доступны» или «готов попробовать переслать данные» и т.д.) при возникновении определенных сетевых событий. Перекрывающие модели также посылают уведомления, но не о наступлении сетевых событий, а об их завершении. При вызове WinSock функции она может либо успешно завершиться, либо завершиться неудачей с кодом ошибки WSA_IO_PENDING. При использовании перекрывающих моделей Вы будете уведомлены о завершении операции. Это значит, что Вам просто надо подождать, пока операция не завершится.

Ценой этого эффективного подхода является трудная реализация. Если Вам не требуется действительно хорошая эффективность, то лучше воспользоваться ранее описанными моделями. Кроме того, операционные системы Windows 9x/ME не полностью поддерживают перекрытые модели ввода/вывода.

Как и модели с уведомлением о сетевых событиях, перекрытие модели так же могут быть реализованы по-разному. Они отличаются способом уведомления: блокирование, polling, процедуры завершения и порты завершения.