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

Пул потоков — идеальное средство в системе, где небольшие единицы работы выполняются регулярно в асинхронном режиме. Хорошим примером может служить вебсервер или сервер любого иного рода, который прослушивает запросы, поступающие на сетевой порт.

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

Поэтому для оптимизации использования системы можно начинать выполнение других элементов работы, пока идет ожидание завершения операции ввода-вывода в другом потоке. Создание пула потоков для управления такой системой — сложнейшая задача, изобилующая массой деталей и ловушек. Однако среда .NET предлагает готовый к использованию пул потоков в форме класса ThreadPool.

Класс ThreadPool подобен классам Monitor и Interlocked в том смысле, что создавать его экземпляры нельзя. Вместо этого для управления пулом потоков, который каждый процесс получает по умолчанию от CLR, применяются статические методы класса ThreadPool.

Фактически о создании пула потоков даже не нужно заботиться. Он создается при первом обращении к нему. Если вы использовали пулы потоков в мире Win32 — будь то системный пул потоков, который появился в Windows 2000, или порты завершения ввода-вывода, — то заметите, что пул потоков .NET аналогичен, но имеет управляемый интерфейс.
Чтобы поставить в очередь элемент в пул потоков, необходимо просто вызвать ThreadPool.QueueUserWorkltem, передав ему экземпляр делегата WaitCallback.

Пул потоков создается при первом вызове этой функции. Метод обратного вызова, представленный делегатом WaitCallback, принимает ссылку на экземпляр System.Object и имеет тип возврата void. Объектная ссылка — необязательный объект контекста, который вызывающий код может применить к перегрузке QueueUserWorkltem. Если контекст не указан, то ссылка на контекст должна быть null. После помещения элемента работы в очередь поток из пула осуществит обратный вызов, как только станет доступным.

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

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

Затем предположим, что сервер принимает четыре запроса, требующих обращения к базе данных, отнимающих определенное время. Если в течение этого времени поступит пятый запрос, свободных потоков для его обслуживания, не окажется.

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

После завершения всех единиц работы, когда система вернется в устойчивое состояние, пул потоков избавится от дополнительных потоков, созданных подобным образом, уничтожив их. Несмотря на невозможность простого управления количеством потоков в пуле, с помощью вызовов GetMinThreads и SetMinThreads можно контролировать минимальное число простаивающих потоков, которые ожидают работы.

Если планируется непосредственная работа с пулом потоков, рекомендуется изучить описание статических методов System. Threading.ThreadPool в документации MSDN. В действительности необходимость в прямой вставке рабочих элементов в пул потоков возникает редко.

Вы можете следить за любыми ответами на эту запись через RSS 2.0 ленту. Вы можете оставить ответ, или trackback с вашего собственного сайта.

Оставьте отзыв

XHTML: Вы можете использовать следующие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

 
Rambler's Top100