День сто восемьдесят первый. #ЗаметкиНаПолях
Многопоточность.
2. Пул потоков в CLR
CLR способна управлять собственным пулом потоков. Для каждого процесса существует свой пул, используемый всеми доменами приложений в CLR. Пул потоков позволяет найти золотую середину в ситуации, когда малое количество потоков экономит ресурсы, а большое позволяет воспользоваться преимуществами многопроцессорных систем, а также многоядерных и гиперпотоковых процессоров. Он действует по эвристическому алгоритму, создавая или уничтожая потоки по мере необходимости.
В пуле различают два типа потоков: рабочие потоки (worker thread) и потоки ввода-вывода (I/O thread). Первые используются для асинхронных вычислительных операций, вторые служат для уведомления кода о завершении асинхронной операции ввода-вывода.
Для добавления в очередь пула потоков асинхронных вычислительных операций обычно вызывают один из методов
Возможны ситуации, когда требуется явно создать поток, исполняющий конкретную вычислительную операцию:
- Поток требуется запустить с нестандартным приоритетом (хотя, этого делать не рекомендуется).
- Чтобы приложение не закрылось до завершения потоком задания, требуется, чтобы поток исполнялся в активном режиме. В примере выше по умолчанию метод Compute выполняется в фоновом потоке, поэтому приложение может прекратить работу перед тем, как завершится выполнение этого метода.
- Задания, связанные с критически важными вычислениями, которые могут выполняться долго, лучше не отдавать на откуп пула потоков, а выделить им отдельный поток.
- Если есть необходимость преждевременно завершить исполняющийся поток через
Продолжение следует…
Источник: Джеффри Рихтер “CLR via C#”. 3-е изд. – СПб.: Питер, 2012. Глава 26.
Многопоточность.
2. Пул потоков в CLR
CLR способна управлять собственным пулом потоков. Для каждого процесса существует свой пул, используемый всеми доменами приложений в CLR. Пул потоков позволяет найти золотую середину в ситуации, когда малое количество потоков экономит ресурсы, а большое позволяет воспользоваться преимуществами многопроцессорных систем, а также многоядерных и гиперпотоковых процессоров. Он действует по эвристическому алгоритму, создавая или уничтожая потоки по мере необходимости.
В пуле различают два типа потоков: рабочие потоки (worker thread) и потоки ввода-вывода (I/O thread). Первые используются для асинхронных вычислительных операций, вторые служат для уведомления кода о завершении асинхронной операции ввода-вывода.
Для добавления в очередь пула потоков асинхронных вычислительных операций обычно вызывают один из методов
QueueUserWorkItem
класса ThreadPool
. В метод передаётся делегат WaitCallback
, а также может передаваться объект состояния state
:static void Main(string[] args)После возвращения управления асинхронным методом, поток возвращается в пул и ожидает следующего задания.
{
Console.WriteLine("Основной поток: вызываем асинхронную операцию");
ThreadPool.QueueUserWorkItem(Compute, 5);
Console.WriteLine("Основной поток: выполняем другую работу...");
Thread.Sleep(10000);
Console.ReadLine();
}
private static void Compute(object state)
{
//Метод выполняется потоком из пула
Console.WriteLine($"В Compute: state={state}");
Thread.Sleep(1000);
}
Возможны ситуации, когда требуется явно создать поток, исполняющий конкретную вычислительную операцию:
- Поток требуется запустить с нестандартным приоритетом (хотя, этого делать не рекомендуется).
- Чтобы приложение не закрылось до завершения потоком задания, требуется, чтобы поток исполнялся в активном режиме. В примере выше по умолчанию метод Compute выполняется в фоновом потоке, поэтому приложение может прекратить работу перед тем, как завершится выполнение этого метода.
- Задания, связанные с критически важными вычислениями, которые могут выполняться долго, лучше не отдавать на откуп пула потоков, а выделить им отдельный поток.
- Если есть необходимость преждевременно завершить исполняющийся поток через
Thread.Abort()
.Продолжение следует…
Источник: Джеффри Рихтер “CLR via C#”. 3-е изд. – СПб.: Питер, 2012. Глава 26.