Как настроить пул потоков для сервера IOCP с подключениями, которые могут выполнять операции блокировки

В настоящее время я работаю над серверным приложением, написанным в стиле проактора, используя select () + пул потоков с динамическим размером (есть простой механизм, основанный на отслеживании незанятых рабочих потоков).

Мне нужно изменить его, чтобы использовать IOCP вместо select () в окнах, и мне интересно, как лучше всего использовать потоки.

Для справки: сервер имеет долговременные соединения с отслеживанием состояния, и любой запрос может потребовать значительной обработки и блокировки. Фактически, большинство запросов связаны с кодом, написанным заказчиком, который может блокироваться по желанию.

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

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

Это лучший способ?


person Bwmat    schedule 30.09.2015    source источник
comment
Не уверен, что понимаю, в чем проблема. Вы можете легко отслеживать, сколько потоков доступно, то есть ожидающих пакета завершения, и запускать дополнительные потоки, если число падает слишком низко.   -  person Harry Johnston    schedule 01.10.2015


Ответы (1)


Похоже, вы прочитали одну из моих статей о IOCP (скорее всего, этот). Это, вероятно, сейчас немного устарело, поскольку вся проблема, которую он сортирует, чтобы избежать (проблема отмены ввода-вывода, если поток, который его выпустил, завершается до завершения ввода-вывода), больше не является проблемой ни с одним из поддерживаемых в настоящее время Microsoft ОС (проблема только в XP и ранее).

Вы правы, заметив, что мой дизайн 2000/2002 годов был неоптимальным с точки зрения переключения контекста; но в то время это работало довольно хорошо, учитывая ограничения базового API.

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

Вам нужно будет отслеживать количество активных потоков IOCP (т.е. не ожидающих GetQueuedCompletionStatus ()) и создавать больше, когда их «слишком мало». Точно так же, как поток собирается вернуться и дождаться GQCS, вы можете проверить, нет ли у вас «слишком много», и если да, пусть вместо этого он умрет.

Я, наверное, должен обновить эти статьи.

person Len Holgate    schedule 02.10.2015