Понимание пулов потоков в C #

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

Зачем мне использовать пулы потоков?

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

Пул потоков - хороший выбор, если вы хотите ограничить количество потоков, которые выполняются в данный момент времени, и хотите избежать накладных расходов на создание и уничтожение потоков в вашем приложении. Это также хороший выбор, когда в вашем приложении много задач, которые необходимо выполнять параллельно или одновременно, и вы хотите улучшить отзывчивость приложения, избегая переключений контекста. Чтобы создать пул потоков, вы можете воспользоваться классом System.Threading.ThreadPool.

В следующем фрагменте кода показано, как можно установить минимальное количество потоков в пуле потоков.

ThreadPool.SetMinThreads (50, 50);

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

Как работает пул потоков?

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

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

Как я могу оптимизировать пул потоков?

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

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

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