ThreadPool behaviour: not growing from minimum size

十年热恋 提交于 2019-12-11 00:35:08

问题


I had set up my thread pool like this:

ThreadPool.SetMaxThreads(10000, 10000);
ThreadPool.SetMinThreads(20, 20);

However, my app started hanging under heavy load. This seemed to be because worker tasks were not executing: I had used ThreadPool.QueueUserWorkItem to run some tasks which in turn used the same method to queue further work. This is obviously dangerous with a limited thread pool (a deadlock situation), but I am using a thread pool not to limit maximum threads but to reduce thread creation overhead.

I can see the potential trap there, but I believed that setting a maximum of 10000 threads on the pool would mean that if an item was queued, all threads were busy, and there weren't 10000 threads in the pool, a new one would be created and the task processed there.

However, I changed to this:

ThreadPool.SetMaxThreads(10000, 10000);
ThreadPool.SetMinThreads(200, 200);

..and the app started working. If that made it start working, am I missing something about how/when the thread pool expands from minimum toward maximum size?


回答1:


Whenever you use the thread pool, you are at the mercy of its "thread injection and retirement algorithm".

The algorithm is not properly documented ( that I know of ) and not configurable.

If you're using Tasks, you can write your own Task Scheduler




回答2:


The job of the threadpool scheduler is to ensure there are no more executing TP threads than cpu cores. The default minimum is equal to the number of cores. A happy number since that minimizes the overhead due to thread context switching. Twice a second, the scheduler steps in and allows another thread to execute if the existing ones haven't completed.

It will therefore take a hour and twenty minutes of having threads that don't complete to get to your new maximum. It is fairly unlikely to ever get there, a 32-bit machine will keel over when 2000 threads have consumed all available virtual memory. You'd have a shot at it on a 64-bit operating system with a very large paging file. Lots of RAM required to avoid paging death, you'd need at least 12 gigabytes.

The generic diagnostic is that you are using TP threads inappropriately. They take too long, usually caused by blocking on I/O. A regular Thread is the proper choice for those kind of jobs. That's probably hard to fix right now, especially since you're happy with what you got. Raising the minimum is indeed a quick workaround. You'll have to hand-tune it since the TP scheduler can't do a reasonable job anymore.




回答3:


The performance issue you described, is similar to what is documented in this ASP.NET KB article,

http://support.microsoft.com/kb/821268

To summarize, you need to carefully choose the parameters (this article mentions the typical settings for default ASP.NET thread pool, but you can apply the trick to your app), and further tune them based on performance testing and the characteristics of your app.

Notice that the more you learn about load, you will see that "heavy load" is no longer a good term to describe the situation. Sometimes you need to further categorize the cases, to include detailed term, such as burst load, and so on.




回答4:


If your logic depends on having a minimum amount of threads you need to change that, urgently.

Setting a MinThreads of 200 (or even 20) is wasting quite a bit of memory. Note that the MaxThreads won't be relevant here, you probably don't have the 10 GB mem for that.

The fact that a min of 200 helps you out is suspicious and as a solution it is probably very brittle.

Take a look at normal Producer/Consumer patterns, and/or use a bounded queue to couple your tasks.



来源:https://stackoverflow.com/questions/9248199/threadpool-behaviour-not-growing-from-minimum-size

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!