Вопрос

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

Это было полезно?

Решение

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

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

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

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

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

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

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

Другие советы

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

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

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

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

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

также

  

new Thread (). Start ()

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

Меня интересовало относительное использование ресурсов для них, и я провел тест на моем двухъядерном ноутбуке 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();
    }

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

Проверьте здесь более раннюю тему:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top