Тема против ThreadPool

137

В чем разница между использованием нового потока и использованием потока из пула потоков? Какие преимущества в производительности есть и почему я должен рассмотреть использование потока из пула, а не одного, который я явно создал? Я имею в виду конкретно .NET здесь, но общие примеры в порядке.

Марк Инграм
источник

Ответы:

110

Пул потоков обеспечит преимущества для частых и относительно коротких операций

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

    • Если вы поставите в очередь 100 задач пула потоков, он будет использовать только столько потоков, сколько уже было создано для обслуживания этих запросов (например, 10). Пул потоков будет делать частые проверки (я думаю, каждые 500 мс в 3.5 SP1), и если есть задачи в очереди, он создаст один новый поток. Если ваши задачи выполняются быстро, то количество новых потоков будет небольшим, и повторное использование 10 или около того потоков для коротких задач будет быстрее, чем создание 100 потоков заранее.

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

    • проверьте здесь для более подробной информации о том, как пул потоков функционирует под капотом

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

@Krzysztof - потоки пула потоков - это фоновые потоки, которые останавливаются по окончании основного потока. Потоки, созданные вручную, по умолчанию являются приоритетными (будут продолжать работать после завершения основного потока), но их можно установить в фоновом режиме перед вызовом Start для них.

Карг
источник
5
Единственное, что меня интересует, это следующий оператор из MSDN ( msdn.microsoft.com/en-us/library/1c9txz50.aspx ) «Фоновый поток выполняется только тогда, когда число выполняемых потоков переднего плана меньше числа процессоров ".. Значит ли это, что при разделении работы между ядрами приоритетные потоки получают приоритет?
cdiggins
1
Can't Нельзя прерывать или прерывать поток из пула потоков. Can't Вы не можете присоединиться к потоку из пула потоков. Для этого нужно использовать некоторые другие механизмы
Зинов
14

.NET управляемый пул потоков: -

  • Размеры зависят от текущей рабочей нагрузки и доступного оборудования.
  • Содержит рабочие потоки и потоки портов завершения (которые специально используются для обслуживания ввода-вывода)
  • Оптимизирован для большого количества относительно коротких операций

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

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

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

Мартин
источник
В .NET вы можете использовать порты завершения без пула потоков? Я предполагал, что асинхронные методы ввода-вывода были единственным способом (в .NET) и что они используют пул потоков
Karg
10

также

new Thread().Start()

порождает поток переднего плана, который не умрет, если вы закроете свою программу. Потоки ThreadPool - это фоновые потоки, которые умирают при закрытии приложения.


источник
11
Вы всегда можете установить поток на фон. По умолчанию они просто передние.
Крис Эриксон,
3
nemo: var t = new Thread (...); t.BackgroundThread = true; t.Start ();
Рикардо Аморес
18
Разъяснение относительно термина «программа». Настольное приложение запускается в процессе и имеет как минимум один приоритетный поток, который управляет пользовательским интерфейсом. Этот процесс будет продолжаться до тех пор, пока у него есть потоки переднего плана. Когда вы закрываете настольное приложение, поток пользовательского интерфейса останавливается, но вы не обязательно останавливаете процесс, если у него есть другие потоки переднего плана.
G-Wiz
8

Мне было любопытно относительное использование ресурсов для них, и я провел тест на моем двухъядерном ноутбуке Intel i5 2012 года, используя сборку выпуска .net 4.0 на Windows 8. Пулы потоков потребовали в среднем 0,035 мс, чтобы запустить, где потоки взяли в среднем 5,06. РС. Другими словами, поток в пуле запускается примерно в 300 раз быстрее для большого количества недолговечных потоков. По крайней мере, в тестируемом диапазоне (100-2000) потоков общее время на поток казалось довольно постоянным.

Это код, который был протестирован:

    for (int i = 0; i < ThreadCount; i++) {
        Task.Run(() => { });
    }

    for (int i = 0; i < ThreadCount; i++) {
        var t = new Thread(() => { });
        t.Start();
    }

введите описание изображения здесь

PeterM
источник
5
Я думаю, это потому, что ThreadPool повторно использует созданные потоки вместо того, чтобы создавать новые (что очень дорого)
fabriciorissetto
3

Проверьте здесь для более ранней темы:

Когда я не должен использовать ThreadPool в .Net?

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

Биоцинк
источник
1

Локальное хранилище потоков не является хорошей идеей с пулами потоков. Это дает потокам "идентичность"; не все темы больше не равны. Теперь пулы потоков особенно полезны, если вам просто нужна группа идентичных потоков, готовых выполнять свою работу без дополнительных затрат на создание.

MSalters
источник
1

Если вам нужно много потоков, вы, вероятно, хотите использовать ThreadPool. Они повторно используют потоки, избавляя вас от накладных расходов на создание потоков.

Если вам нужен только один поток, чтобы что-то сделать, Thread, вероятно, самый простой.

Роб Проуз
источник
1

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

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

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

Supercat
источник
0

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

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

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

Это не означает, что вы не должны создавать свои собственные потоки, но есть условия, при которых имеет смысл использовать пул.

Робин
источник
0

Использование пула - хорошая идея, если вы не знаете или не можете контролировать, сколько потоков будет создано.

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

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

Марко Гиньяр
источник
0

Нить :

  1. Создание потока намного медленнее, чем использование пула потоков.
  2. Вы можете изменить приоритет потока.
  3. Максимальное количество потоков в процессе, связанных с ресурсами.
  4. Поток находится на уровне ОС и контролируется ОС.
  5. Использование потока - лучший вариант, если задача относительно долгая

Thread-Pool :

  1. Запуск потока в пуле потоков намного быстрее, чем непосредственное создание потока.
  2. Вы не можете изменить приоритет запуска потока на основе пула потоков.
  3. Для каждого процесса существует только один пул потоков.
  4. Пул потоков управляется CLR.
  5. Пул потоков полезен для кратковременной работы.
  6. Количество потоков в пуле потоков связано с загрузкой приложения.
  7. Задачи TPL выполняются на основе пула потоков
Сейедрауф Модарреси
источник