Когда я не должен использовать ThreadPool в .Net?
Похоже, что лучше всего использовать ThreadPool, в таком случае, почему это не единственный вариант?
Каков ваш опыт вокруг этого?
Единственная причина, по которой я бы не использовал ThreadPool
дешевую многопоточность, это то, что мне нужно…
- взаимодействовать с запущенным методом (например, чтобы убить его)
- запустить код в потоке STA (это случилось со мной)
- поддерживать ветку после смерти приложения (
ThreadPool
потоки являются фоновыми) - в случае, если мне нужно изменить приоритет потока. Мы не можем изменить приоритет потоков в ThreadPool, который по умолчанию является нормальным.
PS: В статье MSDN «Управляемый пул потоков» содержится раздел под заголовком «Когда не следует использовать потоки пула потоков» , с очень похожим, но несколько более полным списком возможных причин не использования пула потоков.
Есть много причин, по которым вам нужно было бы пропустить ThreadPool
, но если вы их не знаете, то ThreadPool
должно быть достаточно для вас.
В качестве альтернативы посмотрите на новую Parallel Extensions Framework , в которой есть некоторые полезные вещи, которые могут удовлетворить ваши потребности без использования ThreadPool
.
Когда вы собираетесь выполнить операцию, которая займет много времени, или, возможно, непрерывный фоновый поток. Я предполагаю, что вы всегда можете увеличить количество потоков, доступных в пуле, но было бы мало смысла нести расходы на управление потоком, который никогда не будет возвращен пулу.
Пулы потоков имеют смысл всякий раз, когда у вас есть концепция рабочих потоков. В любое время вы можете легко разделить обработку на более мелкие задания, каждое из которых может быть обработано независимо, рабочие потоки (и, следовательно, пул потоков) имеют смысл.
Пулы потоков не имеют смысла, когда вам нужны потоки, которые выполняют совершенно разнородные и несвязанные действия, которые нельзя рассматривать как «задания»; например, один поток для обработки событий GUI, другой для обработки бэкенда. Пулы потоков также не имеют смысла при обработке форм конвейера.
По сути, если у вас есть потоки, которые запускаются, обрабатывают задание и выходят из него, пул потоков, вероятно, является подходящим способом. В противном случае пул потоков действительно не поможет.
К ссорному ответу я бы добавил, что лучше не использовать поток ThreadPool, если вам нужно гарантировать, что ваш поток начнет работать немедленно. Максимальное количество работающих потоков с пулами потоков ограничено для каждого домена приложения, поэтому, возможно, вам придется подождать, пока они все заняты. В конце концов, это называется «рабочий элемент в очереди».
Два предостережения, конечно:
- Вы можете изменить максимальное количество потоков в пуле в коде во время выполнения, так что ничто не помешает вам проверить текущее и максимальное число и при необходимости увеличить максимальное.
- Вращение в новую ветку идет со своим собственным штрафом времени - стоит ли вам попадать в удары, зависит от ваших обстоятельств.
@ Эрик, мне нужно согласиться с Дином. Нитки дорогие. Вы не можете предполагать, что ваша программа работает только одна. Когда все жадны до ресурсов, проблема умножается.
Я предпочитаю создавать свои темы вручную и контролировать их самостоятельно. Это делает код очень простым для понимания.
Это хорошо, когда это уместно. Если вам нужна куча рабочих потоков, все, что вы сделали, - это усложнили свой код. Теперь вам нужно написать код для управления ими. Если вы просто используете пул потоков, вы получите все управление потоками бесплатно. И пул потоков, предоставляемый языком, скорее всего, будет более надежным, более эффективным и менее глючным, чем все, что вы катите для себя.
Thread t = new Thread(new ThreadStart(DoSomething)); t.Start(); t.Join();
Я надеюсь, что у вас обычно есть некоторый дополнительный код между Start()
и Join()
. В противном случае дополнительный поток бесполезен, и вы тратите ресурсы без причины.
Люди слишком боятся ресурсов, используемых потоками. Я никогда не видел, чтобы создание и запуск потока занимал больше миллисекунды. Не существует жесткого ограничения на количество потоков, которые вы можете создать. Использование оперативной памяти минимально. Когда у вас есть несколько сотен потоков, из-за переключений контекста возникает проблема с процессором, поэтому в этот момент вам может понадобиться модный дизайн.
Миллисекунда - это долгое время на современном оборудовании. Это 3 миллиона циклов на машине с частотой 3 ГГц. И опять же, вы не единственный, кто создает темы. Ваши потоки конкурируют за процессор наряду с потоками любой другой программы. Если вы используете не слишком много потоков, как и другая программа, то вместе вы использовали слишком много потоков.
Серьезно, не делайте жизнь более сложной, чем она должна быть. Не используйте пул потоков, если вам не нужно что-то очень конкретное, что он предлагает.
В самом деле. Не делай жизнь более сложной. Если вашей программе требуется несколько рабочих потоков, не изобретайте колесо заново. Используйте пул потоков. Вот почему это там. Вы бы катили свой собственный класс строки?
@Eric
@ Дерек, я не совсем согласен со сценарием, который вы используете в качестве примера. Если вы точно не знаете, что работает на вашей машине, и сколько именно потоков, обработчиков, процессорного времени, оперативной памяти и т. Д. Ваше приложение будет использовать при определенной нагрузке, у вас возникнут проблемы.
Вы единственный целевой клиент для написанных вами программ? Если нет, вы не можете быть уверены в большей части этого. Когда вы пишете программу, вы обычно не представляете, будет ли она эффективно выполняться в одиночку или будет работать на веб-сервере, пораженном атакой DDOS. Вы не можете знать, сколько процессорного времени у вас будет.
Если предположить, что поведение вашей программы изменяется в зависимости от ввода, редко даже точно известно, сколько памяти или процессорного времени займет ваша программа. Конечно, у вас должно быть довольно хорошее представление о том, как ваша программа будет вести себя, но большинство программ никогда не анализируются, чтобы точно определить, сколько памяти, сколько дескрипторов и т. Д. Будет использовано, потому что полный анализ дорог. Если вы не пишете программное обеспечение для реального времени, отдача не стоит усилий.
В общем, утверждение, что вы точно знаете, как будет вести себя ваша программа, является надуманным, а заявление о том, что вы знаете все о машине, выглядит нелепо.
И если честно, если вы не знаете точно, какой метод вы должны использовать: ручные потоки, пул потоков, делегаты и как его реализовать, чтобы сделать именно то, что нужно вашему приложению, у вас возникнут проблемы.
Я не совсем не согласен, но я не понимаю, насколько это актуально. Этот сайт здесь специально, потому что у программистов не всегда есть ответы на все вопросы.
Если ваше приложение достаточно сложное, чтобы требовать регулирования количества потоков, которые вы используете, разве вы не всегда будете хотеть большего контроля, чем то, что дает вам фреймворк?
Нет. Если мне понадобится пул потоков, я буду использовать тот, который предоставляется, до тех пор, пока не обнаружу, что этого недостаточно. Я не буду просто предполагать, что предоставленный пул потоков недостаточен для моих нужд, не подтверждая это.
Я говорю не как человек с теоретическими знаниями. Я пишу и поддерживаю приложения большого объема, которые интенсивно используют многопоточность, и, как правило, не считаю пул потоков правильным ответом.
Большая часть моего профессионального опыта была связана с многопоточными и многопроцессорными программами. Мне также часто приходилось накатывать свое собственное решение. Это не означает, что пул потоков бесполезен или не подходит во многих случаях. Пул потоков создан для обработки рабочих потоков. В случаях, когда подходит несколько рабочих потоков, предоставленный пул потоков должен, как правило, быть первым подходом.
Я говорю не как человек с теоретическими знаниями. Я пишу и поддерживаю приложения большого объема, которые интенсивно используют многопоточность, и, как правило, не считаю пул потоков правильным ответом.
Ах, аргумент от авторитета - но всегда будьте внимательны к людям, которые могут быть в команде ядра Windows.
Никто из нас не спорил с тем фактом, что если у вас есть какие-то особые требования, то .NET ThreadPool может оказаться неправильным. То, на что мы возражаем, - это упрощение затрат на машину для создания потока.
Значительные затраты на создание темы в raison d'etre для ThreadPool в первую очередь. Я не хочу, чтобы мои машины были заполнены кодом, написанным людьми, которые были дезинформированы о расходах на создание потока и, например, не знают, что это вызывает метод, вызываемый в каждой отдельной DLL, которая привязанный к процессу (некоторые из которых будут созданы сторонними разработчиками), который может сильно нагружать загрузку кода, который вообще не должен находиться в оперативной памяти и почти наверняка не должен быть в L1.
Форма иерархии памяти в современных средств машин, которые «отвлекают» процессор является худшее, что вы можете сделать, возможно, и все, кто заботится о своем ремесле должны упорно трудиться, чтобы избежать этого.
MSDN имеет список некоторых причин здесь:
http://msdn.microsoft.com/en-us/library/0ka9477y.aspx
Существует несколько сценариев, в которых целесообразно создавать собственные потоки и управлять ими вместо использования потоков потоков пула:
- Вам нужна передняя нить.
- Вам требуется, чтобы поток имел определенный приоритет.
- У вас есть задачи, которые заставляют поток блокироваться в течение длительного времени. Пул потоков имеет максимальное количество потоков, поэтому большое количество заблокированных потоков пула потоков может помешать запуску задач.
- Вам нужно разместить нити в однопоточной квартире. Все темы ThreadPool находятся в многопоточной квартире.
- Вам необходимо иметь стабильную идентификацию, связанную с потоком, или выделять поток для задачи.
Потоки потоков подходят для задач, которые удовлетворяют обоим следующим критериям:
- Задаче не придется тратить сколько-нибудь значительного времени на ожидание чего-либо
- Все, что ожидает завершения задачи, вероятно, будет ожидать завершения многих задач, поэтому приоритет ее планирования не может сильно повлиять на ситуацию.
Использование потока пула потоков вместо создания нового сэкономит значительное, но ограниченное количество времени. Если это время является значительным по сравнению со временем, которое потребуется для выполнения задачи, скорее всего, уместна задача пула потоков. Однако чем дольше время, необходимое для выполнения задачи, тем меньше выгода от использования пула потоков и тем выше вероятность того, что задача ухудшит эффективность пула потоков.
keep the thread alive after my application has died (ThreadPool threads are background threads)
... я прав. это правда ? если поток пула потоков является фоновым потоком, то поток может работать, когда основной поток умер? объяснить PLZZ