Когда мне не использовать ThreadPool в .Net?
Похоже, что лучший вариант - использовать ThreadPool, и в таком случае, почему это не единственный вариант?
Что вы думаете об этом?
Когда мне не использовать ThreadPool в .Net?
Похоже, что лучший вариант - использовать ThreadPool, и в таком случае, почему это не единственный вариант?
Что вы думаете об этом?
Единственная причина, по которой я бы не стал использовать ThreadPool для дешевой многопоточности, заключается в том, что мне нужно
ThreadPool потока являются фоновыми потоками)PS: статья MSDN " Управляемый пул потоков " содержит раздел под названием " Когда не следует использовать потоки пула потоков " с очень похожим но чуть более полный список возможных причин неиспользования пула потоков.
Существует множество причин, по которым вам нужно пропустить ThreadPool, но если вы их не знаете, то ThreadPool должно быть вам достаточно.
Или посмотрите новый Parallel Extensions Framework, в котором есть несколько полезных вещей, которые могут удовлетворить ваши потребности без использования ThreadPool.
@ Эрик, мне придется согласиться с Дином. Нитки дорогие. Вы не можете предполагать, что работает только ваша программа. Когда все жадны до ресурсов, проблема множится.
Я предпочитаю создавать свои темы вручную и контролировать их сам. Это делает код очень простым для понимания.
Это нормально, когда это уместно. Однако если вам нужна группа рабочих потоков, все, что вы сделали, - это усложнили свой код. Теперь вам нужно написать код для управления ими. Если бы вы просто использовали пул потоков, вы бы получили все управление потоками бесплатно. И пул потоков, предоставляемый языком, скорее всего, будет более надежным, более эффективным и менее глючным, чем все, что вы создаете для себя.
Thread t = new Thread(new ThreadStart(DoSomething)); t.Start(); t.Join();
Я надеюсь, что у вас обычно будет дополнительный код между Start() и Join(). В противном случае дополнительный поток бесполезен, и вы тратите ресурсы без причины.
Люди слишком боятся ресурсов, используемых потоками. Я никогда не видел, чтобы создание и запуск потока занимало больше миллисекунды. Нет жесткого ограничения на количество создаваемых потоков. Использование оперативной памяти минимально. Когда у вас есть несколько сотен потоков, процессор становится проблемой из-за переключений контекста, поэтому в этот момент вы можете захотеть поиграть в свой дизайн.
На современном оборудовании миллисекунда - это долгий время. Это 3 миллиона циклов на машине с частотой 3 ГГц. И опять же, не только вы создаете треды. Ваши потоки конкурируют за ЦП вместе с потоками любой другой программы. Если вы используете не слишком много потоков, как и другая программа, то вместе вы использовали слишком много потоков.
Серьезно, не усложняйте жизнь больше, чем она должна быть. Не используйте пул потоков, если вам не нужно что-то конкретное, что он предлагает.
Верно. Не усложняйте жизнь. Если вашей программе требуется несколько рабочих потоков, не изобретайте велосипед. Используйте пул потоков. Вот почему это есть. Не могли бы вы свернуть свой собственный класс струн?
Пулы потоков имеют смысл всякий раз, когда у вас есть концепция рабочих потоков. Каждый раз, когда вы можете легко разделить обработку на более мелкие задания, каждое из которых может обрабатываться независимо, рабочие потоки (и, следовательно, пул потоков) имеют смысл.
Пулы потоков не имеют смысла, когда вам нужны потоки, которые выполняют совершенно разные и несвязанные действия, которые нельзя рассматривать как «задания»; например, один поток для обработки событий графического интерфейса пользователя, другой - для внутренней обработки. Пулы потоков также не имеют смысла, когда обработка формирует конвейер.
В принципе, если у вас есть потоки, которые запускаются, обрабатывают задание и завершают работу, вероятно, лучше всего использовать пул потоков. В противном случае пул потоков действительно не поможет.
В качестве склочного ответа я бы добавил, что лучше не использовать поток ThreadPool, если вам нужно гарантировать, что ваш поток начнет работу немедленно. Максимальное количество запущенных потоков в пуле ограничено для каждого домена приложения, поэтому вашей работе, возможно, придется подождать, если все они заняты. В конце концов, это называется «рабочий элемент пользователя очереди».
Разумеется, два предостережения:
Я говорю здесь не как человек, обладающий только теоретическими знаниями. Я пишу и поддерживаю приложения с большим объемом, которые интенсивно используют многопоточность, и обычно я не считаю, что пул потоков является правильным ответом.
Ах, аргумент от авторитета - но всегда остерегайтесь людей, которые могут быть в команде ядра Windows.
Никто из нас не спорил с тем фактом, что если у вас есть какие-то особые требования, то .NET ThreadPool может быть неправильным. Мы возражаем против упрощения затрат машины на создание потока.
Существенные затраты на создание потока в первую очередь являются смыслом существования ThreadPool. Я не хочу, чтобы мои машины были заполнены кодом, написанным людьми, которые были дезинформированы о расходах на создание потока, и, например, не знают, что это вызывает вызов метода в каждой отдельной DLL, которая является присоединены к процессу (некоторые из которых будут созданы третьими сторонами), и который вполне может увеличить нагрузку на код, который вообще не должен находиться в ОЗУ и почти наверняка не должен находиться в L1.
Форма иерархии памяти в современной машине означает, что «отвлечение» процессора - это худшее, что вы можете сделать, и всем, кому небезразлично свое дело, следует усердно работать, чтобы этого избежать.
Когда вы собираетесь выполнить операцию, которая займет много времени, или, возможно, в непрерывном фоновом потоке. Я предполагаю, что вы всегда можете увеличить количество потоков, доступных в пуле, но было бы мало смысла нести расходы на управление потоком, который никогда не будет возвращен в пул.
В MSDN есть список причин:
http://msdn.microsoft.com/en-us/library/0ka9477y.aspx
Существует несколько сценариев, в которых целесообразно создавать собственные потоки и управлять ими вместо использования потоков пула потоков:
- Вам нужен поток переднего плана.
- Вам требуется, чтобы поток имел определенный приоритет.
- У вас есть задачи, которые вызывают блокировку потока на длительные периоды времени. Пул потоков имеет максимальное количество потоков, поэтому большое количество заблокированных потоков пула потоков может помешать запуску задач.
- Вам нужно поместить потоки в однопоточную квартиру. Все потоки ThreadPool находятся в многопоточном апартаменте.
- У вас должна быть стабильная идентификация, связанная с потоком, или вы должны выделить поток для задачи.
Потоки Threadpool подходят для задач, отвечающих обоим следующим критериям:
Использование потока threadpool вместо создания нового позволит сэкономить значительное, но ограниченное количество времени. Если это время значительно по сравнению со временем, которое потребуется для выполнения задачи, задача пула потоков, вероятно, подходит. Однако чем больше времени требуется для выполнения задачи, тем меньше польза от использования пула потоков и тем выше вероятность того, что задача снижает эффективность пула потоков.
@ Эрик
@Derek, я не совсем согласен со сценарием, который вы используете в качестве примера. Если вы точно не знаете, что работает на вашем компьютере и сколько именно потоков, дескрипторов, процессорного времени, ОЗУ и т. Д., Которые ваше приложение будет использовать при определенной нагрузке, у вас проблемы.
Вы единственный целевой клиент для программ, которые вы пишете? В противном случае вы не можете быть уверены в большей части этого. Когда вы пишете программу, вы обычно не имеете ни малейшего представления о том, будет ли она эффективно работать в одиночку или на веб-сервере, подвергающемся DDOS-атаке. Вы не можете знать, сколько процессорного времени у вас будет.
Предполагая, что поведение вашей программы изменяется в зависимости от ввода, редко можно даже точно знать, сколько памяти или процессорного времени будет потреблять ваша программа. Конечно, вы должны иметь довольно хорошее представление о том, как будет вести себя ваша программа, но большинство программ никогда не анализируются, чтобы точно определить, сколько памяти, сколько дескрипторов и т. Д. Будет использовано, потому что полный анализ стоит дорого. Если вы не пишете программное обеспечение для работы в реальном времени, окупаемость не стоит затраченных усилий.
В общем, утверждение о том, что вы точно знаете, как будет вести себя ваша программа, надумано, а заявление о том, что он знает все о машине, выглядит нелепо.
И, честно говоря, если вы точно не знаете, какой метод вам следует использовать: ручные потоки, пул потоков, делегаты и как его реализовать, чтобы делать именно то, что нужно вашему приложению, у вас проблемы.
Я не полностью не согласен, но я действительно не понимаю, насколько это актуально. Этот сайт здесь специально потому, что у программистов не всегда есть ответы на все вопросы.
Если ваше приложение достаточно сложное, чтобы требовать регулирования количества используемых вами потоков, разве вам почти всегда не понадобится больше контроля, чем то, что дает вам фреймворк?
Нет. Если мне нужен пул потоков, я буду использовать тот, который предоставлен, до тех пор, пока я не обнаружу, что его недостаточно. Я не буду просто предполагать, что предоставленный пул потоков недостаточен для моих нужд, не подтверждая это.
Я говорю здесь не как человек, обладающий только теоретическими знаниями. Я пишу и поддерживаю приложения с большим объемом, которые интенсивно используют многопоточность, и обычно я не считаю, что пул потоков является правильным ответом.
По большей части мой профессиональный опыт связан с многопоточными и многопроцессорными программами. Мне также часто приходилось использовать собственное решение. Это не означает, что пул потоков бесполезен или не подходит во многих случаях. Пул потоков создан для обработки рабочих потоков. В случаях, когда уместно несколько рабочих потоков, предоставленный пул потоков обычно должен быть первым подходом.