The thread pool is an important concept. But I find that there seems to be something missing in the discussion on this topic. As a supplement to the information, as well as the references required for future articles, I am here to talk about the thread pool in a complete and simple way, and. The basis of various thread pools in net. More detailed information will not be expanded, and we shall have the opportunity to discuss the details in detail. This time, it is still an "outline" of the nature of the hope that we can understand some of the concepts of this aspect.
The role of the thread pool
In fact, the "thread pool" is the pool of objects used to hold "threads".
In a program, if the cost of creating an object is too high and the object can be reused, then we tend to prepare a container to hold a batch of such objects. Thus, when we want to use this object, we do not need to create one each time, and directly from the container to take out a ready-made object. By saving the overhead of creating objects, program performance naturally increases. This container is the "pool". It is easy to understand that because of the object pool, there must be a "return" action after the object is exhausted, so that the object can be put back into the pool and used again the next time it is needed.
For example, when we use ADO to connect to SQL Server. NET Framework will automatically help us maintain a connection pool, which is because the cost of recreating a connection is relatively high, and "reuse" is more cost-effective. However, some friends may say, we obviously create a SqlConnection object every time, where there is a "reuse" Ah? This is because. NET Framework to clear the "connection pool" for the programmer completely hidden the concept. Each time we create a new SqlConnection object, the "database connection" that is used inside the object is reused. Why do you always have to "close" (dispose or close) when you're done with SqlConnection objects? In fact, there is no disconnection of the database connection, just put this connection back to the connection pool. The next time you create a new SqlConnection object, this connection can be used again.
Since we're getting objects from the pool every time, who created them and when? This is done by the various object pools from the rows, depending on the situation. For example, you can specify the number of objects in the pool when you create the object pool, and all at once, but you can also create a request if you find that there are no more objects left in the pool. You can also "advance" to prepare a part, "in the matter" as necessary to continue to add. You can also do "smart" some, for example, to add or delete some objects according to the actual situation, even to the demand "trend" to "forecast", in the idle time to create more objects for "contingency." The changes are hard to say.
Of course, they are similar in principle and purpose. I believe the above text has also cleared the role of the thread pool: Because creating a thread is expensive, we use the thread pool to try to reuse threads. It's that simple.
CLR Thread pool
In. NET, the CLR thread corresponds to the operating system thread, which you can simply assume. The thread object in net encapsulates an operating system thread and comes with some data (such as GC Handle) required in a Managed Environment 1. The CLR thread pool is the object pools that hold these CLR threads.
When we write a program, we can use the two static methods of the ThreadPool class: QueueUserWorkItem and Unsafeuserqueueworkitem add tasks to the CLR thread pool (a Workcallback delegate object). The difference between the two methods is that the former collects the executioncontext of the caller, that is, the execution information of the current thread (such as authentication or language culture), so that the task will eventually execute in the environment of the "create" moment 2--the latter will not. Therefore, if you compare the absolute performance of two methods, the unsafe method is notch above. However, it is usually recommended to use the QueueUserWorkItem method, because preserving the execution context avoids a lot of trouble, and this performance loss is not really what it is.
The CLR thread pool plays a large role in the. NET Framework, and other features rely on the CLR threading pool in addition to being used by programmers. such as the ThreadPool.RegisterWaitForSingleObject method, or the System.Threading.Timer component-- It is also more important and more likely to be hidden: After a request is taken, ASP will also hand over the requested task to the CLR thread pool for execution-note that they are only adding tasks at most, and it does not mean that the task executes immediately. All tasks added to the CLR thread pool will be executed at the right time-either immediately, or perhaps a little, or even longer.
When you add a task to the CLR thread pool, the task is temporarily placed in a queue and executed at the appropriate time. So what's the "Right time"? The simple generalization is that there are idle threads in the thread pool, or that the number of threads managed by thread pools has not reached the upper limit. If there is an idle thread, the thread pool will immediately have it pick up a task to execute. In the second case, the thread pool creates a new thread object. The CLR thread pool has an upper limit because the operating system manages too many threads instead of causing performance degradation. Different hosting environments set different caps. After the. NET 2.0 SP1, a normal Windows application, such as the console or WINFORM/WPF, will be set to processor number * 250. That is, if your machine is 2 2-core CPUs, the default upper limit for the capacity of the CLR thread pool is 1000, which means that it can manage up to 1000 threads at the same time-in many cases this is already a scary number, and if you don't think that's enough, Then you should consider whether your implementation can be improved.
For an ASP. NET application, the CLR thread pool capacity represents the maximum number of requests that an application can execute concurrently. For an ASP. NET execution Environment hosted on IIS, this value is determined by the global configuration. This configuration is in the System.web/processmodel node of the Machine.config file and is the maxWorkerThreads attribute, which determines the number of threads allocated for a single processor. If this value is 40 and the machine has 4 processors (2 * 2CPU), then the current configuration of this machine is represented at the same time, ASP. NET can process up to 160 requests at a time. Some references recommend that you modify it to 80-100 threads per processor, as long as you modify the corresponding property value.
Since there is a maximum value, there is a corresponding minimum value, which represents the minimum number of threads that the CLR thread pool "always keeps". Because threads consume resources, such as by default, each thread will get a stack space of 1MB size 3. So it is a waste to keep too many idle threads in the system for resources. Therefore, after a large number of tasks are processed by the CLR thread pool, the thread is gradually freed until it reaches the minimum value. The minimum number of threads in the CLR thread pool ensures that, with fewer tasks, the new task can be executed immediately, eliminating the time to create a new thread. In a normal application This value is "processor number * 1" and in an ASP. NET application This value is configured in the System.web/processmodel node's minWorkerThreads attribute in the Machine.config file 4.
At some point you may encounter situations in which a large number of tasks suddenly come up in an instant, and the execution time of each task is said to be short, but enough to cause the thread pool to quickly allocate hundreds of threads. If the peak is calm after that, then it is bound to cause a lot of idle threads, and this overhead is very noticeable for the performance loss. Therefore, the CLR thread pool restricts the creation of threads to no more than 2 per second. This allows the CLR thread pool to use a relatively small number of threads to accomplish all of the work 5, even when a large amount of tasks are acquired at some point in an instant.
However, there is also a situation that deserves consideration. For example, for a busy Web application, a large number of connections are poured in as soon as they are opened. Because threads are created with limited speed, the number of requests that can be executed is only slowly increasing. For this scenario where you anticipate a large number of threads, and the busy situation lasts for some time, limiting the creation speed of threads can lead to damage efficiency. At this point, you can manually set the minimum number of threads for the CLR thread pool. If there are fewer threads in the CLR thread pool at this point, then the system will immediately create a certain number of threads to achieve this minimum value. The interface for setting and getting the minimum number of threads for the CLR thread pool is:
public static class threadpool{public static void getminthreads (out int workerthreads, out int completionportthreads ); public static bool SetMinThreads (int workerthreads, int completionportthreads);}
The roles and uses of these two interfaces should be obvious (see MSDN If you don't understand them), where the workerthreads parameter is the minimum number of threads for the CLR thread pool, and completionportthreads involves our next discussion of the IO thread pool, There is not much to unfold here. In addition to the methods for setting and reading the minimum number of CLR threads, ThreadPool includes these interfaces:
public static class threadpool{public static void getmaxthreads (out int workerthreads, out int completionportthreads ); public static bool SetMaxThreads (int workerthreads, int completionportthreads); public static void GetAvailableThreads (out int workerthreads, out int completionportthreads);}
It is important to note that these values, whether set or acquired, have no relation to the number of processors. In other words, when you run a normal. NET application on a 2 * 2CPU machine:
- Calling the GetMaxThreads method will get 1000, which means that the CLR thread pool has a maximum capacity of 1000 (250 * 4) instead of 250.
- Calling SetMinThreads and passing in 100 indicates that the minimum number of threads owned by the CLR thread pool is 100, not 400 (100 * 4).
A brief description of the CLR thread pool is here for the time being. If you have any further questions please ask, I will add.
Note 1: strictly speaking, the thread object and the system thread correspondence have some details to consider. For example, the thread object only creates an operating system thread that binds to it when it is really start.
NOTE 2: ExecutionContext is an important and useful object, for example, what should I do if an operator interface element throws an exception in an asynchronous task in WinForms or WPF?
Note 3: When you create a thread using the Windows API or the thread class, you can specify the size of its stack space, but the thread in the CLR thread pool only uses the default value-but this default value is also related to the managed environment, such as a normal application default of 1MB. and ASP. NET is 250KB, which means that the ASP-overflow exception is more likely to be generated by the NET application.
Note 4: Unfortunately, for processmodel node data, ASP. NET only reads global configuration information in Machine.config, which means that we cannot use Web. config to configure different parameters for different applications. If we were to implement application-level configuration, we would have to use the API provided in the ThreadPool class to set it up, as mentioned later.
Note 5: for this, you might want to do a math problem: line Cheng suddenly poured into 500 tasks, each task block or pause for 5 seconds, each thread consumes 1MB of memory, assuming that the thread pool is currently empty, and has sufficient capacity, this thread is created fast enough, So how much time and memory does it take to complete these tasks with limited and unlimited thread creation speeds?
Reprint: http://www.cnblogs.com/JeffreyZhao/archive/2009/07/22/thread-pool-1-the-goal-and-the-clr-thread-pool.html
Discussion on thread pool (top): The role of thread pool and CLR thread pool