In multi-threaded programs, there are often two situations:
One scenario: In an application, a thread spends most of its time waiting for an event to occur before it can respond
This is generally solved by using threadpool (thread pool);
Another scenario: The line accesses tile is dormant, but is periodically awakened
This is usually solved by using a timer (timer);
This article is about the thread pool alone [ThreadPool]
ThreadPool class MSDN Help information: http://msdn.microsoft.com/zh-cn/library/system.threading.threadpool.aspx#Y0
To add a task to the thread pool:
ThreadPool.QueueUserWorkItem (New WaitCallback (method name));
Overload
ThreadPool.QueueUserWorkItem (New WaitCallback (method name), parameters);
Because ThreadPool is a static class, it does not need to be instantiated.
The primary control for the thread pool has a control thread number size:
Threadpool.setmaxthreads method
public static bool SetMaxThreads (int workerthreads,int completionportthreads)
Parameters:
-
WorkerThreads
-
Type: System.Int32
The maximum number of worker threads in the thread pool.
-
completionPortThreads
-
Type: System.Int32
The maximum number of asynchronous I/O threads in the thread pool.
Example:
123456789101112131415161718192021222324252627282930313233 |
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.Threading;
namespace
多线程池试验
{
class
Program
{
public
static void
Main()
{
ThreadPool.SetMaxThreads(3, 3);
for
(
int
i = 0; i < 50; i++)
{
thr t =
new
thr();
ThreadPool.QueueUserWorkItem(
new
WaitCallback(t.ThreadProc), i);
}
Console.WriteLine(
"断点测试"
);
Thread.Sleep(100000);
Console.WriteLine(
"运行结束"
);
}
public
class thr
{
public
void
ThreadProc(
object
i)
{
Console.WriteLine(
"Thread["
+ i.ToString() +
"]"
);
Thread.Sleep(1000);
}
}
}
}
|
Output Result:
You'll find the breakpoint test on it, what's the reason?
Reason:
1. Thread pool startup and termination is not controlled by our program, I do not know, you can email me if you know [email protected]
2. When a thread in a thread pool finishes executing, there is no return value.
In a word, we don't know what the thread pool has done, so how do we solve the problem of task completion?
The operating system provides a "semaphore" (ManualResetEvent)
ManualResetEvent allows threads to communicate with each other by signaling. Typically, this communication involves a task that a thread must complete before other threads are made. When a thread starts an activity (this activity must be completed before other threads can start), it calls Reset to put ManualResetEvent in a non-terminating state, which can be considered a control ManualResetEvent. A thread that calls WaitOne on ManualResetEvent will block and wait for the signal. When the control thread finishes the activity, it calls Set to emit a signal that the waiting thread can continue. And frees all waiting threads. Once it is terminated, ManualResetEvent will remain signaled (that is, the thread of the call to WaitOne will return immediately, not block) until it is manually reset. You can control the initial state of a ManualResetEvent by passing a Boolean value to the constructor, true if the initial state is signaled, or false if it is in the terminating state.
See Msdn:http://msdn.microsoft.com/zh-cn/library/system.threading.manualresetevent.aspx for details
The main use of
Eventx.waitone (Timeout.infinite, true); Blocks the current thread until the current WaitHandle receives a signal.
Eventx.set (); Sets the event state to the signaled state, allowing one or more waiting threads to continue.
The Modified program:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859 |
using
System;
using
System.Collections.Generic;
using
System.Linq;
using System.Text;
using
System.Threading;
namespace
多线程池试验
{
class
Program
{
public
static
void Main()
{
//新建ManualResetEvent对象并且初始化为无信号状态
ManualResetEvent eventX =
new
ManualResetEvent(
false
);
ThreadPool.SetMaxThreads(3, 3);
thr t =
new
thr(15, eventX);
for
(
int
i = 0; i < 15; i++)
{
ThreadPool.QueueUserWorkItem(
new
WaitCallback(t.ThreadProc), i);
}
//等待事件的完成,即线程调用ManualResetEvent.Set()方法
//eventX.WaitOne 阻止当前线程,直到当前 WaitHandle 收到信号为止。
eventX.WaitOne(Timeout.Infinite,
true
);
Console.WriteLine(
"断点测试"
);
Thread.Sleep(10000);
Console.WriteLine(
"运行结束"
);
}
public
class
thr
{
public
thr(
int
count,ManualResetEvent mre)
{
iMaxCount = count;
eventX = mre;
}
public
static
int
iCount = 0;
public
static
int
iMaxCount = 0;
public
ManualResetEvent eventX;
public
void
ThreadProc(
object i)
{
Console.WriteLine(
"Thread["
+ i.ToString() +
"]"
);
Thread.Sleep(2000);
//Interlocked.Increment()操作是一个原子操作,作用是:iCount++ 具体请看下面说明
//原子操作,就是不能被更高等级中断抢夺优先的操作。你既然提这个问题,我就说深一点。
//由于操作系统大部分时间处于开中断状态,
//所以,一个程序在执行的时候可能被优先级更高的线程中断。
//而有些操作是不能被中断的,不然会出现无法还原的后果,这时候,这些操作就需要原子操作。
//就是不能被中断的操作。
Interlocked.Increment(
ref
iCount);
if
(iCount == iMaxCount)
{
Console.WriteLine(
"发出结束信号!"
);
//将事件状态设置为终止状态,允许一个或多个等待线程继续。
eventX.Set();
}
}
}
}
}
|
Output Result:
C # multithreaded learning thread pool [ThreadPool] (GO)