Томский политехнический университет
Опубликован: 23.01.2013 | Доступ: свободный | Студентов: 1158 / 192 | Длительность: 12:09:00
Лекция 3:

Многопоточность в .NET Framework

Пул потоков CLR

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

Для управления списком потоков предусмотрен класс ThreadPool, который по мере необходимости уменьшает и увеличивает количество потоков в пуле до максимально допустимого значения. Значение максимально допустимого количества потоков в пуле может изменяться. В случае двуядерного ЦП оно по умолчанию составляет 1023 рабочих потоков и 1000 потоков ввода-вывода.

Для того, чтобы запросить поток из пула для обработки вызова метода, можно использовать метод QueueUserWorkItem(). Этот метод перегружен, чтобы в дополнение к экземпляру делегата WaitCallback позволить указывать необязательный параметр System.Object для специальных данных состояния.

Ниже приведен пример приложения, в котором сначала читается и выводится на консоль информация о максимальном количестве рабочих потоков и потоков ввода-вывода. Затем в цикле for метод JobForAThread() назначается потоку из пула потоков за счет вызова метода ThreadPool.QueueUserWorkltem() и передачи делегата типа WaitCallback. Пул потоков получает этот запрос и выбирает из пула один из потоков для вызова метода. Если пул еще не существует, он создается и запускается первый поток:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ThreadingPools
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 0; i < 5; i++)
            {
                ThreadPool.QueueUserWorkItem(JobForAThread);
                Thread.Sleep(2000);
            }
            Console.ReadLine();
        }
        static void JobForAThread(object state)
        {
            for (int i = 0; i < 10; i++)
            {
             Console.WriteLine("Цикл {0},  выполняется внутри потока {1}", i,
             Thread.CurrentThread.ManagedThreadId);
             Thread.Sleep(10);
            }
        }
    }
}

Результат выполнения работ программы представлен на Рис. 4.1.

Результаты выполнения пула потоков

увеличить изображение
Рис. 4.1. Результаты выполнения пула потоков

Преимущества CLR потоков:

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

Пулы потоков очень просты в применении, однако обладают рядом ограничений, которые перечислены ниже:

  • Все потоки в пуле потоков являются фоновыми. В случае завершения работы всех приоритетных потоков в процессе работа всех фоновых потоков тоже останавливается. Сделать поток из пула приоритетным не удастся.
  • Нельзя изменять приоритет или имя находящего в пуле потока. Все потоки в пуле представляют собой потоки многопоточного апартамента (multi-threaded apartment - МТА), а многие СОМ-объекты требуют использования потоков однопоточного апартамента (single-threaded apartment - STA).
  • Потоки в пуле подходят для выполнения только коротких задач. Если необходимо, чтобы поток функционировал все время (как, например, поток средства проверки орфографии в Word), его следует создавать с помощью класса Thread.
  • Нельзя создавать потоки с фиксированной идентичностью (Чтобы можно было прерывать их или находить по имени).
Владимир Каширин
Владимир Каширин

Вопрос по Курсу: "Параллельное программирование с использованием MS VisualStudia 2010".

При компиляции Самостоятельного задания (одновременная отрисовка прямоугольников, эллипсов и выдача в текст-бокс случайного числа) среда предупреждает: suspend - устаревшая команда; примените monitor, mutex и т.п.

Создаётся впечатление, что Задание создано в более поздней среде, чем VS 2010.