如果我的线程池的运作方式的理解是正确的,其目的之一是限制可以在给定的时间内创建一个进程中的工作线程数。 例如,如果你设置MaxThreads到5,然后调用QueueUserWorkItem 30倍,30个请求将被做出了线程池,但只有那些请求5将通过一个新的线程来提供服务,而其他25个请求将被添加到队列和服务的一个在时间前面的请求完成,现有的线程变为可用。
在下面的代码,但是,调用了Thread.Sleep(-1),保证了DoSomething的()方法永远不会返回,这意味着当前线程将永远不会成为提供给后续请求。
但我的方式了解一个线程池的作品不可能是正确的,因为如果它是正确的下面的代码将只打印数字0-4,而不是0-29。
有人可以请解释线程池如何工作以及为什么下面的代码不会做我认为应该把它做什么?
static void DoSomething(object n)
{
Console.WriteLine(n);
Thread.Sleep(-1);
}
static void Main(string[] args)
{
ThreadPool.SetMaxThreads(5, 5);
for (int x = 0; x < 30; x++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(DoSomething), x);
}
Console.Read();
}
ThreadPool.SetMaxThreads(5, 5)
指活动线程数为5(如果你有超过5个CPU核心),并不意味着线程池只能创建5个线程。 线程= CPU核心* 250的线程池最大数目。
之后Thread.Sleep
,线程是无效的,所以不会影响到其他线程的执行。
但我的方式了解一个线程池的作品不可能是正确的,因为如果它是正确的下面的代码将只打印数字0-4,而不是0-29。
是你的假设是非常正确的。
由于u必须排队在一个线程池和作业30个作业将睡InfiniteTime,他们将永远不会结束,ThreadPool类会等待一定的时间间隔,以创造新的线程,但不会超过线程的最大数量。
注意
Console.Read()是保持你的后台线程活着。
用品
从MSDN
许多应用程序创建一个花了大量时间在睡眠状态,等待一个事件的发生线程。 其他线程可能进入只需要定期唤醒以轮询更改或更新状态信息的睡眠状态。 线程池使您可以通过提供您的应用程序的工作线程池是由系统管理更有效地使用线程。 一个线程监视几个等待操作的状态排队到线程池。 当一个等待操作完成后,从线程池中的工作线程执行相应的回调函数。
当所有的线程池中的线程已分配给的任务,线程池不会立即开始创建新的空闲线程。 为了避免不必要的线程分配堆栈空间,它在创建新的区间空闲线程。 该区间是目前半秒,虽然也可以在.NET Framework的未来版本更改。
在托管线程池中的线程是后台线程。 也就是说,他们的IsBackground性质为真。 这意味着,一个线程池线程不会让应用程序运行的所有前台线程都已经退出了。
这可能是Thread.sleep代码(-1)是不是做你的期望。
参数的Int32:针对线程被阻塞的毫秒数。 指定零(0),以指示该线程应暂停,以允许其它等待的线程来执行。 指定无限无限期地阻塞线程。
http://msdn.microsoft.com/en-us/library/d00bd51t.aspx
你应该考虑的任务, http://msdn.microsoft.com/en-us/library/dd235608.aspx把它看成线程池2.0
通常,线程池创建多个线程等于CPU内核的数量。 有创建多个线程,因为只有一个线程可以通过核心的时间来处理没有必要。 但是,当任务排队到线程池的时间超过0.5秒执行,线程池创建一个额外的线程来处理剩下的任务在队列中。 所以,如果你排队了很多沉重的任务,线程池,它会创造出很多额外的线程来模拟多任务和“平行”执行所有任务。 但总的执行时间是一样的,无需额外的线程,而且,因为创建线程是相当繁重的操作的话会少。 这就是为什么推荐小任务线程池,以避免这实际上不会带来任何好处创建额外的线程。
你可以阅读更多关于线程池阿尔巴哈利的文章。 其实,他有很好的一套约线程的文章出现。