【问题标题】:Is there a limit on how many worker items you can queue in the threadpool?您可以在线程池中排队的工作项目数量是否有限制?
【发布时间】:2011-08-21 23:17:44
【问题描述】:

你可以在线程池队列中放入多少项目有限制吗?

 ThreadPool.QueueUserWorkItem(someCallBack);

MSDN 没有说明限制是什么,如果您通过它会发生什么(它会暂时停止正在发布的线程吗?还是会引发异常?)

举个例子。如果我只是在队列中排队 100,000 个项目怎么办。那会奏效吗?

【问题讨论】:

    标签: .net clr queue threadpool


    【解决方案1】:

    排队项目的数量没有理论上的限制,它应该不断向队列中添加回调,直到你用尽了你的资源。

    但是,您为什么要首先添加那么多?如果您要添加这么多项目,它们很可能是非常短暂的,您最好为手头的任务找出更好的分区方案。

    【讨论】:

    • 你说得对,这个例子有点夸张。我只是想知道在将东西扔到队列中以在某个时候被拾取时是否需要有额外的逻辑。所以我是否需要担心这个并创建我自己的队列来限制然后重新发布,或者在大多数意图和目的中线程队列是一个“无限”队列
    • 如果您想限制它们,您应该创建自己的队列管理器来限制您发布的项目数量,并让您的每个工作人员在完成时发出信号。然后,经理将对剩余的项目进行排队,直到它们全部处理完毕。我认为这样做的唯一好处是您有机会在工作线程被启动之前中止处理。否则我会把他们都排好队然后放他们走。此外,关于使用 GetMaxThreads 和 SetMaxThreads 的评论与线程池中的项目数无关 - 这不是被要求的。
    【解决方案2】:

    您可以使用 Threadpool.GetMaxThreads() 和 Threadpool.SetMaxThreads() 来确定/修改池中的最大线程数。

    当您对工作项进行排队时,如果可能,它将使用池中的空闲线程开始执行,或者如果所有线程都忙,它将等到线程可用后再开始执行。如果您对某些内容进行排队并且没有可用的空闲线程,则不会出现错误。

    【讨论】:

    • 那么你的意思是正在排队的线程会“等待”吗?还是它只是将所有内容排队并继续,同时随着线程可用,队列被一个一个清空?
    • "在线程池线程可用之前,所有超过该数量的请求都会排队。"据我了解,它只是将它们放入队列并立即返回。
    • Vladislav Zorov 是对的,将项目添加到队列中的线程根本不等待,QueueUserWorkItem 方法将立即返回并允许调用线程继续处理。排队的项目将保留在队列中,直到线程可以开始执行。
    • OP 询问的是队列的大小而不是池的大小。
    【解决方案3】:

    我相信唯一的限制是最多 UInt32.MaxValue 可以在队列中。如果您使用 32 位 CLR,您会提前很久就会耗尽内存,因此您永远无法达到该限制。

    我猜在 64 位 CLR 上理论上你可以达到这个限制,但我认为你需要大约 850GB 的内存来测试它。在开始耗尽内存(在安装了 8GB RAM 的机器上)之前,我使用 6-7GB 的工作集获得了大约 40,000,000 个排队的项目。

    我不知道如果你达到极限会发生什么。快速查看带有反射器的 mscorlib,它甚至可能不会抛出异常,而只是溢出并产生不可预知的结果。

    如果你有一台内存大约 1TB 的机器,这里有一个小测试 sn-p 来尝试自己看看会发生什么:)

    class Program
        {
            static void Main(string[] args)
            {
                for (long i = 0; ; ++i)
                {
                    bool succeeded = ThreadPool.QueueUserWorkItem(SleepCallBack);
                    if ((i % 1000) == 0)
                    {
                        Console.WriteLine(i);
                    }
                    if (!succeeded) break;
                }
                Console.Read();
            }
    
            private static void SleepCallBack(object stateInfo)
            {
                Thread.Sleep(System.Threading.Timeout.Infinite);
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-01
      • 1970-01-01
      相关资源
      最近更新 更多