我试图理解ThreadPool的作用,我有这个.NET示例:
class Program
{
static void Main()
{
int c = 2;
// Use AutoResetEvent for thread management
AutoResetEvent[] arr = new AutoResetEvent[50];
for (int i = 0; i < arr.Length; ++i)
{
arr[i] = new AutoResetEvent(false);
}
// Set the number of minimum threads
ThreadPool.SetMinThreads(c, 4);
// Enqueue 50 work items that run the code in this delegate function
for (int i = 0; i < arr.Length; i++)
{
ThreadPool.QueueUserWorkItem(delegate(object o)
{
Thread.Sleep(100);
arr[(int)o].Set(); // Signals completion
}, i);
}
// Wait for all tasks to complete
WaitHandle.WaitAll(arr);
}
}
这是否会以2个(int c
)为一组运行50个“任务”直到它们全部完成?或者我不明白它到底是做什么的。
答案 0 :(得分:3)
如果你有一点时间,我真的会推荐这个:
http://www.albahari.com/threading/
这是一本优秀的读物,奠定了基础,并从基本线程到并行编程。在尝试修改线程池代码之前,我建议你对前两章有一个基本的把握! :)
答案 1 :(得分:1)
通过设置最小个线程数,您要求.NET运行时唯一要做的就是为线程池分配至少2个线程。你不是要求限制本身只有2。
因此,无法保证您的程序将使用多少线程。这取决于您的系统和许多其他因素。
我做了一个简单的测试(对你的程序进行微小改动以跟踪进入睡眠呼叫的同时线程)最多在一次运行中为4,在另一次运行中为3,在另一次运行中为7,在另一次运行中为10,等等。
您真的不需要更改线程池大小。
你想要完成什么?
答案 2 :(得分:0)
来自SetMinThreads上的MSDN文档:
当需求低时,实际数字 线程池线程可以在下面 最小值。
因此,您指定的值不保证2个工作线程将对排队的项目起作用。它可能是1个工作线程(因为你在循环中将它们排队,它可能在下一个排队之前完成),或者它可以根据系统资源和必须完成的工作量来使用更多
如果您真的想看看发生了什么,请查看Process Monitor之类的工具。您可以监视进程的线程创建并跟踪它们何时被创建,销毁等。它将真正帮助您了解您的应用程序(和底层框架)正在做什么。
希望这有帮助。
答案 3 :(得分:0)
背景:.NET线程池管理线程的常规方法可能很麻烦。它可以很好地限制由资源争用引起的问题,但它是以牺牲线程创建速度为代价的。为了提高线程池的工作线程性能,设计人员允许一种机制,允许创建一定数量的线程而无需通过队列进程。
SetMinThreads()指定应该“按需”创建的线程数,也就是说,只需启动就可以不对当前线程数进行任何检查或排队慢慢加速。
将会发生的是框架会立即创建前两个线程,就像您使用Thread.Start手动设置它们并将其踢掉一样。除此之外,直到当前的MaxThreads计数,框架将开始排队对工作线程的请求并以指定的时间间隔启动它们(默认情况下,250ms,我相信这也可以配置)以避免资源冲突。这样做的原因是,如果您想象一个循环访问资源的循环行为,进行一些计算,然后将结果写入其他地方,您可以看到5个线程近似同时启动会导致logjam尝试获取到第一个资源。在MaxThreads阈值处,队列停止;在完成之前不会创建新的线程。
因此,仅仅根据您的代码的性质,将安排50个单独的工作任务,但不是所有50个工作任务都将同时运行;运行时将允许两个立即启动,然后等待250毫秒或直到一个结束,然后开始下一个。因为线程将在不到250ms的时间内执行和终止,所以你不可能同时看到超过2个工作线程执行;在创建第三个之前的等待将永远不会发生,因为“无限制”的工作线程将首先释放,而等待的那个线程在等待时间到期之前被启动,然后时钟将被下一个重置。