需要帮助理解.net ThreadPool

时间:2011-02-21 23:11:22

标签: c# multithreading visual-studio-2010 threadpool

我试图理解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个“任务”直到它们全部完成?或者我不明白它到底是做什么的。

4 个答案:

答案 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个工作线程执行;在创建第三个之前的等待将永远不会发生,因为“无限制”的工作线程将首先释放,而等待的那个线程在等待时间到期之前被启动,然后时钟将被下一个重置。