2010-01-10 73 views
0

我使用QueueUserWorkItem()函数来调用线程池。
我试了很多工作。 (约30000)
但由任务管理器我的应用程序只按了4〜5个线程后,我按下了开始按钮。
我读了MSDN,它表示线程限制的默认数量约为500.
为什么只有少数线程在我的应用程序中生成?
我正在加快我的应用程序,我dout这个线程池是减慢我的应用程序的原因之一。

我的线程池只能做4〜5个线程。为什么?

感谢

回答

1

了解threadpool调度程序如何工作很重要。它旨在根据机器的功能微调运行线程的的数量。您的机器可能只能同时运行两个线程,双核CPU是当前的标准。也许四个。

所以,当你将一堆线程转储到它的膝上时,它通过仅激活两个线程而开始。其余的人在队列中,等待CPU核心可用。只要这两个线程中的一个完成,它就会激活另一个线程。它每秒两次,评估未完成的活动线程发生了什么。它粗略地假设那些线程被阻塞,因此没有进展并且允许另一个线程激活。你现在有三个正在运行的线程。启动500个线程(默认的最大线程数)需要249秒。

很明显,这种行为表明了一个线程应该做什么来适合作为线程池线程运行。它应该很快完成并且不会经常阻止。请注意,对I/O请求的阻止是分开处理的。

如果此行为不适合您,则可以使用常规线程。它将立即开始运行,并与程序(和操作系统)中的其他线程竞争CPU时间。创建30,000个这样的线程是不可能的,没有足够的虚拟内存可用于此。一个32位操作系统在2000线程以南的某个地方冒出来,消耗所有可用的虚拟内存。在分页文件耗尽之前,您可以在64位操作系统上获得大约50,000个线程。不建议在生产程序中测试这些限制。

+0

是的我发现我的机器有四个核心。没有线程池我的应用程序运行速度慢了4倍。 –

0

线程池是有这样就可避免针对其原因恰恰是线程是昂贵的每一个异步操作创建一个线程。如果你想要30,000个线程,你会为线程堆栈使用大量的内存,并浪费了很多CPU时间来执行上下文切换。现在创建这么多的线程是合理的,如果你有30,000个CPU核心...

1

我想你可能误解了线程池的使用。产生线程和杀死线程涉及Windows内核,并且是一项昂贵的操作。如果您不断需要线程来执行异步操作,然后将它们扔掉,则会执行很多系统调用。

所以线程池实际上是一组创建线程一旦而不是退出时,他们完成他们的任务实际上输入等待另一个项目为queueuserworkitem。线程池将根据您的进程需要并发多少个线程来调整自身。如果你想测试这个写这个代码:

for(int i = 0; i < 30000; i++) 
{ 
    ThreadPool.QueueUserWorkItem(myMethod); 
} 

你会看到这将创建一大堆线程。可能不是30000,因为ThreadPool开始通过函数调用工作,所创建的一些线程将被重用。