Подтвердить что ты не робот

Каков правильный способ использования ThreadPool?

Если мое понимание того, как работает ThreadPool, является правильным, одна из его целей - ограничить количество рабочих потоков в процессе, который может быть создан в данный момент времени. Например, если вы установите MaxThreads на 5, а затем вызовите QueueUserWorkItem 30 раз, 30 запросов будут отправлены в ThreadPool, но только 5 из этих запросов будут обслуживаться новым потоком, в то время как остальные 25 запросов будут добавлены в очередь и обслуживается один раз по мере поступления предыдущих запросов и существующих потоков.

Однако в приведенном ниже коде вызов Thread.Sleep(-1) гарантирует, что метод DoSomething() никогда не вернется, а это означает, что текущий поток никогда не станет доступен для последующих запросов.

Но мое понимание того, как работает ThreadPool, не может быть правильным, потому что, если бы оно было правильным, код ниже печатал бы только числа 0-4, а не 0-29.

Может кто-нибудь объяснить, как работает ThreadPool и почему приведенный ниже код не делает то, что я думал, что он должен делать?

    static void DoSomething(object n)
    {
        Console.WriteLine(n);
        Thread.Sleep(-1);
    }

    static void Main(string[] args)
    {
        ThreadPool.SetMaxThreads(5, 5);
        for (int x = 0; x < 30; x++)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(DoSomething), x);
        }
        Console.Read();
    }
4b9b3361

Ответ 1

ThreadPool.SetMaxThreads(5, 5)

означает, что число активных потоков равно 5 (если у вас более 5 ядер процессора), не означает, что ThreadPool может создавать только 5 потоков. Максимальное количество потоков ThreadPool = CPU Core * 250.

После Thread.Sleep поток неактивен, поэтому он не повлияет на выполнение других потоков.

Ответ 2

Но мое понимание того, как работает ThreadPool, не может быть правильным, потому что, если бы это было правильно, приведенный ниже код напечатал бы только числа 0-4, а не 0-29.

Да, ваше предположение очень правильное.

Так как u поставил в очередь 30 заданий в ThreadPool, и задания будут спать для InfiniteTime, они никогда не закончатся, класс ThreadPool будет ждать определенного интервала для создания нового потока, но не будет превышать максимальное количество потоков.

Примечание

Console.Read() сохраняет ваш фоновый поток живым.

Статьи

От MSDN

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


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


Потоки в пуле управляемых потоков - это фоновые потоки. Что есть, их свойства IsBackground верны. Это означает, что ThreadPool thread не будет поддерживать приложение, запущенное передние потоки завершены.

Ответ 3

Возможно, что Thread.Sleep(-1) не выполняет то, что вы ожидаете.

Параметр Int32: Число миллисекунд, для которых поток заблокирован. Укажите нуль (0), чтобы указать, что этот поток должен быть приостановлен, чтобы разрешить выполнение других ожидающих потоков. Укажите Infinite, чтобы заблокировать поток неограниченно.

http://msdn.microsoft.com/en-us/library/d00bd51t.aspx

Вы должны посмотреть в Задачи, http://msdn.microsoft.com/en-us/library/dd235608.aspx Подумайте об этом как Threadpool 2.0

Ответ 4

Обычно ThreadPool создает число потоков, равное количеству ядер ЦП. Нет необходимости создавать больше потоков, поскольку только один поток может обрабатываться ядром за раз. Но, когда задача, поставленная в очередь на ThreadPool, занимает более 0,5 секунды для выполнения, ThreadPool создает дополнительный поток для обработки оставшихся задач в очереди. Итак, если вы ставите в очередь много тяжелых задач ThreadPool, он создаст много дополнительных потоков для эмуляции многозадачности и выполнения всех задач в "параллельном". Но общее время выполнения будет таким же, как без дополнительных потоков, более того, это будет еще меньше, потому что создание потока довольно тяжелое. Именно поэтому ThreadPool рекомендуется для небольших задач, чтобы избежать создания дополнительных потоков, которые на самом деле не приносят никаких преимуществ.

Подробнее о ThreadPool можно прочитать в статье статьи в Albahari. На самом деле у него есть хороший набор статей о потоковом использовании.