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

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

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

Что вы думаете об этом?


person Vaibhav    schedule 13.08.2008    source источник


Ответы (9)


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

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

PS: статья MSDN " Управляемый пул потоков " содержит раздел под названием " Когда не следует использовать потоки пула потоков " с очень похожим но чуть более полный список возможных причин неиспользования пула потоков.

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

Или посмотрите новый Parallel Extensions Framework, в котором есть несколько полезных вещей, которые могут удовлетворить ваши потребности без использования ThreadPool.

person Community    schedule 13.08.2008
comment
u сказал: - Сохраняйте поток после того, как мое приложение умерло (потоки ThreadPool являются фоновыми потоками), но насколько я знаю, что фоновый поток всегда заканчивается основным потоком. так что ты говоришь ?? - person Mou; 30.04.2013
comment
@Mou: К сожалению, я понятия не имею, что вы пытаетесь сказать. - person ; 30.04.2013
comment
Если вы читаете это, значит, теперь вам следует использовать Задачи вместо ThreadPool. - person ; 21.04.2015
comment
ты сказал _1 _... я прав. это правда ? если поток пула потоков является фоновым потоком, тогда поток может работать, когда основной поток умер? объясни пожалуйста - person Mou; 21.04.2015
comment
@Mou Прочтите это msdn.microsoft.com/en -us / library / h339syd0 (v = против 110) .aspx - person ; 21.04.2015
comment
Я столкнулся с проблемами №1 (добавление поддержки CancellationToken к длительному (5+ минут) чистого (достаточного) вызова функции в сторонней библиотеке) и №2 (одновременный рендеринг WPF ImageSource ... требуется для каждого параллельного рендеринга для начала и завершения в одном потоке STA, но затем его можно заморозить для отображения из других потоков) в том же приложении, так что это правильный ответ для меня. В большинстве случаев пул управляемых потоков (или одна из множества других вещей, таких как TPL, которые в конечном итоге его используют) является правильным, но иногда правильный ответ - создать новый поток и продолжить свою жизнь. - person Joe Amenta; 13.06.2015
comment
В качестве ответа я ожидал более практических примеров по SO, а не только заявлений из MSDN. Но все равно спасибо! - person eRaisedToX; 10.02.2021

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

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

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

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

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

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

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

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

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

person Derek Park    schedule 13.08.2008
comment
Некоторые люди накручивают свою собственную оболочку на массив символов и используют ее как строку ... так что это возможно ... и это тоже печально. - person Andrei Rînea; 09.10.2008
comment
Я проголосовал против. Это не ответ; это ответ на чужой. - person hwiechers; 13.08.2012
comment
Это достаточно хороший ответ. Но 22 голоса за сейчас? Это не то хорошо. В Редмонде не проводится массовое голосование, не так ли? - person ; 22.08.2012
comment
@Will, это комментарий 4-летней давности. Это в среднем менее половины голосов за месяц. Вряд ли невероятный уровень голосов. - person Derek Park; 21.09.2012
comment
@hwiechers, это половина ответа, половина ответа. У SO не было комментариев, когда это было опубликовано, и я не хочу тратить время, чтобы просмотреть все мои старые ответы и преобразовать их в комментарии. - person Derek Park; 21.09.2012
comment
@DerekPark: И не надо. Я пришел сюда из-за флага NAA. Затем из-за жгучей ревности оставил комментарий. Просто шутки. - person ; 21.09.2012
comment
@ Уилл, не беспокойся. Я знал, что вы шутите о голосовании (мы смогли набрать больше 22 голосов за 4 года), но не был уверен, насколько серьезно вы относились к хорошему комментарию "Это не тот". :) - person Derek Park; 26.09.2012
comment
Идея о том, что не следует предполагать, что код - единственное, что работает, - это ИМХО аргумент против использования потоков пула потоков для любого значительного количества операций, которые, как ожидается, займут больше 10 мс или около того. Если производительность одной части приложения зависит от своевременного выполнения обратных вызовов завершения ввода-вывода, то, если другая часть приложения заполняет очередь пула потоков с помощью длительных методов, может ухудшить производительность первой части гораздо больше, чем если бы вторая часть использует дискретные потоки, особенно если эти методы тратят много времени на блокировку. - person supercat; 22.02.2015

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

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

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

person Derek Park    schedule 13.08.2008
comment
Можете ли вы объяснить, что пулы потоков замечаний не имеют смысла, когда обработка формирует конвейер? Предположим, у меня есть рабочие элементы, которые нужно сжать, а затем зашифровать, а сжатие использует в 10 раз больше вычислений для шифрования. Почему бы не использовать пул потоков с соотношением компрессора к потокам шифрования 10: 1? - person Cheeso; 26.03.2009
comment
Пулы потоков обычно используются, когда программе нужно выполнять независимые отдельные части работы. Если существует связь между рабочими потоками (например, в конвейере), то на самом деле у вас нет сценария пула потоков. - person Derek Park; 03.04.2009

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

Разумеется, два предостережения:

  1. Вы можете изменить максимальное количество потоков в пуле потоков в коде во время выполнения, поэтому ничто не мешает вам проверять текущее и максимальное число и при необходимости увеличивать максимальное.
  2. Создание новой нити влечет за собой отдельную потерю времени - стоит ли вам принимать удар, зависит от ваших обстоятельств.
person Dogmang    schedule 13.08.2008

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

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

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

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

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

person Will Dean    schedule 13.08.2008

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

person Quibblesome    schedule 13.08.2008

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

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

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

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

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

  1. The task will not have to spend any significant time waiting for something to happen
  2. Anything that's waiting for the task to finish will likely be waiting for many tasks to finish, so its scheduling priority isn't apt to affect things much.

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

person supercat    schedule 30.04.2013

@ Эрик

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

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

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

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

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

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

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

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

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

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

person Derek Park    schedule 13.08.2008