Когда мне не следует использовать ThreadPool в .Net?[закрыто]

StackOverflow https://stackoverflow.com/questions/10274

Вопрос

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

Похоже, лучший вариант — использовать ThreadPool, и в этом случае почему это не единственный вариант?

Каков ваш опыт по этому поводу?

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

Решение

Единственная причина, по которой я бы не стал использовать ThreadPool для дешевой многопоточности, если мне нужно…

  1. взаимодействовать с запущенным методом (например, чтобы убить его)
  2. запустить код на STA-поток (это случилось со мной)
  3. сохранить поток живым после того, как мое приложение умерло (ThreadPool потоки являются фоновыми потоками)
  4. на случай, если мне понадобится изменить приоритет потока.Мы не можем изменить приоритет потоков в ThreadPool, который по умолчанию является нормальным.

P.S.: Статья MSDN «Управляемый пул потоков» содержит раздел под названием, «Когда не следует использовать потоки пула потоков», с очень похожим, но немного более полным списком возможных причин неиспользования пула потоков.

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

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

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

@Эрик, мне придется согласиться с Дином.Нитки дорогие.Вы не можете предполагать, что ваша программа — единственная работающая.Когда все жадны к ресурсам, проблема умножается.

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

Это хорошо, когда это уместно.Однако если вам нужна группа рабочих потоков, все, что вам нужно сделать, это усложнить код.Теперь вам нужно написать код для управления ими.Если бы вы просто использовали пул потоков, вы бы получили все управление потоками бесплатно.И пул потоков, предоставляемый языком, скорее всего, будет более надежным, более эффективным и менее ошибочным, чем тот, который вы создадите сами.

Thread t = new Thread(new ThreadStart(DoSomething));  
t.Start();  
t.Join();  

Я надеюсь, что между ними обычно будет дополнительный код. Start() и Join().В противном случае дополнительный поток бесполезен, и вы зря тратите ресурсы.

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

Миллисекунда – это длинный время на современном оборудовании.Это 3 миллиона циклов на машине с частотой 3 ГГц.И опять же, вы не единственный, кто создает темы.Ваши потоки конкурируют за процессор вместе с потоками любой другой программы.Если вы используете не слишком много потоков, как и другая программа, то вместе вы использовали слишком много потоков.

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

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

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

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

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

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

Два замечания, конечно:

  1. Вы можете изменить максимальное количество потоков в пуле потоков в коде во время выполнения, поэтому ничто не помешает вам проверить текущее и максимальное количество и увеличить максимальное, если необходимо.
  2. Раскручивание новой нити влечет за собой штраф по времени — стоит ли вам принимать удар, зависит от ваших обстоятельств.

Я не говорю как кто -то с только теоретическим знанием здесь.Я пишу и поддерживаю приложения с большим объемом, которые используют многопользовательское использование, и я обычно не считаю, что пул потоков является правильным ответом.

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

Никто из нас не спорил с тем фактом, что если у вас есть какие-то особые требования, то .NET ThreadPool может оказаться неподходящим решением.Мы возражаем против упрощения затрат машины на создание потока.

В первую очередь значительные затраты на создание потока являются смыслом существования ThreadPool.Я не хочу, чтобы мои машины были заполнены кодом, написанным людьми, которые были дезинформированы о затратах на создание потока и, например, не знают, что это приводит к вызову метода в каждой отдельной DLL, которая прикрепленный к процессу (некоторые из которых будут созданы сторонними организациями), и который вполне может вызвать нагрузку кода, который вообще не обязательно должен находиться в оперативной памяти и почти наверняка не должен быть в L1.

Форма иерархии памяти в современной машине означает, что «отвлечение» процессора — это худшее, что вы можете сделать, и каждый, кто заботится о своем ремесле, должен усердно работать, чтобы избежать этого.

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

В MSDN есть список некоторых причин:

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

Есть несколько сценариев, в которых целесообразно создавать и управлять своими собственными потоками вместо использования потоков пула потоков:

  • Вам нужен поток переднего плана.
  • Вам необходимо, чтобы поток имел определенный приоритет.
  • У вас есть задачи, которые приводят к блокировке потока на длительный период времени.Пул резьбов имеет максимальное количество потоков, поэтому большое количество заблокированных резьбов бассейна может предотвратить запуск задач.
  • Вам нужно разместить потоки в однопоточной квартире.Все потоки ThreadPool находятся в многопоточном апартаменте.
  • Вам необходимо иметь стабильную идентификацию, связанную с потоком, или посвятить поток задаче.

Потоки пула потоков подходят для задач, которые соответствуют обоим следующим критериям:

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

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

@Эрик

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

Вы единственный целевой потребитель программ, которые вы пишете?В противном случае вы не можете быть уверены в большей части этого.Когда вы пишете программу, вы обычно понятия не имеете, будет ли она эффективно выполняться в одиночку или будет работать на веб-сервере, подвергшемся DDOS-атаке.Вы не можете знать, сколько процессорного времени у вас будет.

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

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

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

Я не совсем согласен, но не понимаю, какое это имеет отношение.Этот сайт создан специально потому, что у программистов не всегда есть ответы на все вопросы.

Если ваше приложение достаточно сложное и требует регулирования количества используемых потоков, разве вам почти всегда не понадобится больше контроля, чем то, что дает вам платформа?

Нет.Если мне понадобится пул потоков, я буду использовать тот, который имеется, до тех пор, пока я не обнаружу, что его недостаточно.Я не буду просто предполагать, что предоставленного пула потоков недостаточно для моих нужд, не подтвердив это.

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

Большая часть моего профессионального опыта связана с многопоточными и многопроцессорными программами.Мне также часто приходилось внедрять собственное решение.Это не означает, что пул потоков бесполезен или неуместен во многих случаях.Пул потоков создан для обработки рабочих потоков.В случаях, когда подходят несколько рабочих потоков, предоставленный пул потоков обычно должен быть первым подходом.

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