ThreadPool SetMaxThreads и SetMinThreads Magic Number

Существует ли магическое число или формула для установки значений SetMaxThreads и SetMinThreads для ThreadPool? У меня есть тысячи долго работающих методов, которые требуют выполнения, но я просто не могу найти идеальное соответствие для установки этих значений. Любой совет будет принят с благодарностью.


person Benny    schedule 11.01.2010    source источник


Ответы (3)


Минимальное количество потоков по умолчанию — это количество ядер вашей машины. Это хорошее число, обычно нет смысла запускать больше потоков, чем у вас есть ядер.

Максимальное количество потоков по умолчанию в 250 раз превышает количество ядер, имеющихся в .NET 2.0 SP1 и более поздних версиях. Здесь огромное пространство для дыхания. На четырехъядерной машине для достижения этого максимума потребуется 499 секунд, если ни один из потоков не завершится за разумное время.

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

Достижение максимума не является здоровым. На четырехъядерной машине только стеки этих потоков будут потреблять гигабайт виртуальной памяти. Получение OOM весьма вероятно. Подумайте о снижении максимального количества потоков, если это ваша проблема. Или рассмотрите возможность запуска нескольких обычных потоков, которые получают пакеты работы из потокобезопасной очереди.

person Hans Passant    schedule 11.01.2010
comment
Пожалуйста, взгляните на мой связанный вопрос, один пользователь предложил мне использовать [ThreadPool], согласно тому, что вы говорите, я не думаю, что это хорошая идея, возможно, вы можете мне помочь. - person Shimmy Weitzhandler; 03.11.2011
comment
@Hans Passant: это вряд ли правильно, во-первых, максимальное количество потоков по умолчанию зависит от версии .NET Framework, используемой приложением (например, 25 на ядро ​​в 2.0). Во-вторых, увеличение минимального количества потоков приводит к тому, что потоки могут запускаться без задержки, пока не будет достигнуто минимальное количество (они не будут запускаться, если они не нужны). Если достигнута минимальная задержка, новые потоки будут создаваться только с задержкой между ними, что приведет к повышению производительности при длинных операциях (> 500 мс), но к падению производительности при коротких операциях. - person haze4real; 09.11.2012
comment
@HansPassant - если кто-то создает потоки, которые могут быть заблокированы в ожидании внешнего ввода-вывода, я думаю, что бывают ситуации, когда лучший минимум действительно будет выше, чем количество ядер. Потому что заблокированный поток по-прежнему считается минимальным, верно? (Я понимаю, что это не будет иметь значения более чем на несколько секунд, потому что после этого планировщик все равно создаст эти дополнительные потоки. Просто убедитесь, что я понимаю аргументацию.) - person ToolmakerSteve; 04.03.2018

Как правило, магическое число — оставить его в покое. ThreadPool хорошо справляется с этим.

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

Профилируйте свое приложение, чтобы найти правильный номер.

person Reed Copsey    schedule 11.01.2010
comment
Если бы я изменил максимальное количество потоков (и минимальное количество потоков?), у меня было бы два параметра: рабочие потоки и потоки порта завершения. Для чего нужно количество потоков порта завершения ?? - person Benny; 11.01.2010
comment
Кроме того, если я оставлю ThreadPool в покое, не устанавливая минимальные/максимальные потоки, я столкнусь с OutOfMemoryException, и все потоки завершатся ошибкой. - person Benny; 11.01.2010
comment
Это другая проблема - вы можете уменьшить объем работы, регулируя ее, но нехватка памяти на самом деле не имеет ничего общего с многопоточностью... - person Reed Copsey; 11.01.2010
comment
@ReedCopsey Не могли бы вы помочь мне с этот связанный вопрос? Спасибо - person Shimmy Weitzhandler; 03.11.2011
comment
не рекомендуется ограничивать работу, чтобы избежать OOM-Exception, вызванного слишком большим количеством потоков, используемых ThreadPool. Идея ThreadPool заключается в управлении асинхронной рабочей нагрузкой, поэтому вы должны оставить регулирование ThreadPool и не делать это самостоятельно. Если у вас закончилась память из-за ThreadPool, вы должны уменьшить MaxThreads (1 поток примерно требует 1 МБ). - person haze4real; 09.11.2012
comment
@ haze4real - предположительно, OOM происходит не из-за ThreadPool напрямую, а потому, что программист создает потоки, каждый из которых использует много памяти. В этом случае регулирование — это именно то, что должен сделать программист: ограничить количество активных потоков для этой конкретной задачи. Тем не менее, я согласен с тем, что возиться с параметрами пула потоков — не лучший способ регулирования — вместо этого его следует регулировать в источнике: код, который запускает эти потоки, должен отслеживать, сколько активных потоков, и блокировать себя всякий раз, когда это происходит. достигает установленного им самим предела. - person ToolmakerSteve; 04.03.2018

Если вам нужен лучший контроль, вы можете НЕ использовать встроенный ThreadPool. Хорошая замена есть на http://www.codeproject.com/KB/threads/smartthreadpool.aspx.

person Michael Bray    schedule 11.01.2010
comment
Я пытался использовать SmartThreadPool, но безрезультатно. После того, как я поставил в очередь все рабочие элементы, я попытался использовать WaitForIdle (у меня есть логика после выполнения), и он никогда не блокируется, а просто движется дальше. Может быть между клавиатурой и компом, но пока не разобрался - person Benny; 11.01.2010
comment
Я знаю, что этому посту 10 лет. Но чего бы это ни стоило... По моему профессиональному опыту, почти во всех случаях было бы плохим решением думать, что пользовательская реализация будет работать лучше, чем то, что команды .NET сделали за многие годы. Конечно, могут быть крайние случаи, когда реализация пула потоков общего назначения будет неоптимальной, но это очень редко. - person Hulvej; 04.05.2021