Home > Article > Backend Development > C# multithreading-detailed introduction to thread pool
Thread Process pool System.Threading.ThreadPool can be used to send work items, process asynchronous I/O, wait on behalf of other threads, and process timers. Basic usage:
public void Main() { ThreadPool.QueueUserWorkItem(JobForAThread); // 将某工作交给线程池}void JobForAThread(object state) // 线程要执行的工作:满足 委托WaitCallback {for (int i = 1; i <= 5; i++) { Console.WriteLine("Running Thread {0},Step {1}", Thread.CurrentThread.ManagedThreadId, i); Thread.Sleep(500); } }
After executing the ThreadPool.QueueUserWorkItem() method, the processor willautomaticallyselect a thread in the pool to process the "work content".
1. If the thread pool is not running yet, a thread pool will be created and the first thread will be started.
2. If the thread pool is already running and there is at least one idle thread, the thread pool will hand over the "work content" to the idle thread for processing.
3. If there are no idle threads in the thread pool at that time, the job will be in a waiting state until there is an idle thread to process it.
ThreadPool.GetMaxThreads() method is used to retrieve the number of thread pool requests that can be active at the same time.
int vWorkerThreads; int vCompletionPortThreads; ThreadPool.GetMaxThreads(out vWorkerThreads, out vCompletionPortThreads); Console.WriteLine("池中辅助线程的最大数{0},池中异步 I/O 线程的最大数{1}", vWorkerThreads, vCompletionPortThreads);
You can set the number of thread pool requests that can be active at the same time through the ThreadPool.SetMaxThreads() method.
ThreadPool.SetMaxThreads(5, 4);
However, you cannot set the number of auxiliary threads or the number of asynchronous I/O completion threads to be less than the number of computer processors. The thread pool is very simple to use, but there are some restrictions:
1. All threads in the thread pool are background threads. If all foreground threads of a process end, all background threads will stop. The thread entering the pool cannot be changed to the foreground thread.2. You cannot set the priority or name for the thread entering the pool.
3. Threads in the pool can only be used for short tasks. If the thread wants to run all the time, you should use the Thread class to create a thread.
Give JobForAThread() job taskPass parameters object state, call:
public void Main() { ThreadPool.QueueUserWorkItem(JobForAThread,"这是传递给工作内容的参数"); // 添加工作的同时,传递参数Console.ReadKey(); // 让主线程等待,否则“一闪而过” }void JobForAThread(object state) { Console.WriteLine("收到信息:{0}", (string)state); // 处理传进来的数据for (int i = 1; i <= 5; i++) { Console.WriteLine("Running Thread {0},Step {1}", Thread.CurrentThread.ManagedThreadId, i); Thread.Sleep(500); } }
Simple control operation
一 Under normal circumstances, after the "work" is handed over to the thread pool, it is out of control. It will be automatically decided by the processor when to start execution (of course, only if there are idle threads). You can use the following code to let the job start executing after the specified time.
ManualResetEvent mManualEvent;public void Main() { mManualEvent = new ManualResetEvent(false); // 实例ThreadPool.QueueUserWorkItem(JobForAThread); Console.WriteLine("{0} 任务已经交给线程池了,但是它没有执行.", DateTime.Now.ToString("HH:mm:ss")); Thread.Sleep(10000); // 等待 10smManualEvent.Set(); // 发出信号,让线程继续执行 Console.ReadKey(); // 让主线程等待,否则“一闪而过” }void JobForAThread(object state) { mManualEvent.WaitOne(); // 等待 “ mManualEvent.Set();” 这一句执行(发送信号)Console.WriteLine("{0} 现在开始执行任务啦.", DateTime.Now.ToString("HH:mm:ss"));for (int i = 1; i <= 5; i++) { Console.WriteLine("Running Thread {0},Step {1}", Thread.CurrentThread.ManagedThreadId, i); Thread.Sleep(500); } }
After the work is handed over to the thread pool, the thread is blocked in mManualEvent when executing the work. .WaitOne(); In this sentence, the work will not continue to execute subsequent code until the main thread sends a signal 10s later. This is a
"false start"control operation, which essentially does not allow the specified work to start working when expected. Here, when initializing the ManualResetEvent object, the parameter false means that the signal is set to the "blocking state" by default, and the signal is set to the "continuable state" through the code mManualEvent.Set();. On the contrary, you can put the thread into "blocked state" through the code mManualEvent.Reset();.
When there is , you need to wait for all threads in the thread pool to complete execution before continuing to execute some other code.
AutoResetEvent[] mAutoResetEvent;public void Main() { mAutoResetEvent = new AutoResetEvent[]{new AutoResetEvent(false), // 默认信号为 阻塞new AutoResetEvent(false),new AutoResetEvent(false) };for (int i = 0; i < 3; i++) // 创建3个工作 { Thread.Sleep(1000); ThreadPool.QueueUserWorkItem(JobForAThread, i); } Console.WriteLine("所有工作已经添加到池中..."); WaitHandle.WaitAll(mAutoResetEvent); // 等待 mAutoResetEvent 中所有信号变为 继续 后,继续后面代码Console.WriteLine("所有工作已经完成了"); Console.ReadKey(); // 让主线程等待,否则“一闪而过” }void JobForAThread(object state) {int vJobIndex = (int)state; Console.WriteLine("Job {0} Started.", vJobIndex);for (int i = 1; i <= 5; i++) { Console.WriteLine("Running Thread {0},Step {1},Job {2} ", Thread.CurrentThread.ManagedThreadId, i, vJobIndex); Thread.Sleep(500); } mAutoResetEvent[vJobIndex].Set(); }
[]
The above is the detailed content of C# multithreading-detailed introduction to thread pool. For more information, please follow other related articles on the PHP Chinese website!