Threadpool QueueUserWorkItem без использования SetMaxThreads, GetMaxThreads

Я использую Threadpool для параллельной обработки в С# .NET 2.0.

Код :

int MAXThreads=GetConfigValue("MaxThreadLimit"); //This value is read from app.config

ManualResetEvent[] doneEvents=new ManualResetEvent[MAXThreads];
for(int i=0;i<MaxThreads,i++)
{

doneEvents[i]=new ManualResetEvent(false);

//create workload
DoProcess job=new DoProcess(workload,doneEvents[i]);
ThreadPool.QueueUserWorkItem(job.ThreadPoolCallBack,i);

}
WaitHandle.WaitAll(doneEvents);

//proceed

Class DoProcess
{
private WorkLoad load;
private ManualResetEvent doneEvent;
public DoProcess(WorkLoad load,ManualResetEvent doneEvent)
{
this.load=load;
this.doneEvent=doneEvent;
}
public void ThreadPoolCallBack(object index)
{
//Do Processing
doneEvent.Set();
}
}

Значение MAXThreads считывается из конфигурации, но я думаю, что это не имеет ничего общего с фактическим количеством сгенерированных потоков. Только несколько ~ 4-5 потоков справляются со всей нагрузкой. Я хочу, чтобы количество потоков было зафиксировано где-то около 20. Как я могу этого добиться? Я что-то упустил?.. Решает ли SetMaxThreads эту проблему?.. Приведенный выше код будет работать на четырехъядерном процессоре.


person techknowfreak    schedule 19.05.2012    source источник
comment
Это не поддерживается моей организацией :(   -  person techknowfreak    schedule 20.05.2012
comment
QueueUserWorkItem без использования SetMaxThreads приведет к увеличению количества потоков?   -  person zangw    schedule 20.01.2014


Ответы (3)


Вместо этого вам нужно будет установить минимальное количество потоков.

В общем, это не очень хорошая идея, запуск большего количества потоков, чем количество ядер процессора, обычно приводит к меньшему выполнению работы, поскольку операционная система тратит время на их перестановку. Эти переключатели контекста недешевы. Менеджер пула потоков делает все возможное, чтобы ограничить количество активных потоков количеством ядер. Разрешение запуска большего количества потоков только тогда, когда существующие не завершаются вовремя. До максимального количества потоков. Огромное значение по умолчанию, 1000 в вашем случае.

Увеличивайте минимальное количество потоков только тогда, когда эти рабочие потоки не выполняют достаточно работы, потому что они слишком часто блокируются при вводе-выводе. В этом случае вам действительно следует рассматривать объекты Thread вместо потоков пула потоков.

person Hans Passant    schedule 19.05.2012
comment
Отличный ответ, однако в случае обширного ввода-вывода я бы предложил использовать подход на основе APM (Stream.BeginRead/Stream.EndRead). Асинхронный ввод-вывод не будет блокировать поток во время выполнения операции ввода-вывода. - person undefined; 19.05.2012

Также есть SetMinThreads в классе ThreadPool. Установка для min и max одного и того же значения «должна» исправить количество потоков, но что на самом деле происходит под капотом, можно только догадываться.

MSDN:

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

Таким образом, установка минимального количества потоков на 20 должна дать вам не менее 20 потоков в пуле.

person Tudor    schedule 19.05.2012

Предполагая, что это приложение C#, вы можете использовать модель параллельного программирования .NET Framework 4 и ограничить количество потоков до 20.

Parallel.For(0, n, new ParallelOptions { MaxDegreeOfParallelism = 20 }, 
  i => 
  { 
    DoWork(i);
  }); 

Однако, если это веб-сайт/приложение, лучше вообще держаться подальше от ThreadPool, за исключением действительно небольших заданий, 1-2 потоков, потому что вы не хотите голодать ThreadPool. И НИКОГДА не устанавливайте максимальное или минимальное количество потоков в коде, потому что это повлияет на весь ваш сайт и на все другие сайты, использующие один и тот же пул потоков.

В этом случае я рекомендую вместо этого использовать SmartThreadPool.

person Chris Gessler    schedule 19.05.2012
comment
@techknowfreak — это веб-приложение? - person Chris Gessler; 19.05.2012
comment
это консольное приложение Windows. - person techknowfreak; 19.05.2012
comment
@techknowfreak - я все еще думаю, что управление собственным пулом - это правильный путь. SmartThreadPool очень прост в использовании. - person Chris Gessler; 19.05.2012