【问题标题】:Check number of idle cores when creating .Net 4.0 Parallel Task创建 .Net 4.0 并行任务时检查空闲内核的数量
【发布时间】:2010-11-01 08:09:37
【问题描述】:

我的问题可能听起来有点幼稚,但我对多线程编程很陌生。

我正在编写一个处理传入外部数据的应用程序。对于到达的每个数据,都会按以下方式创建一个新任务:

System.Threading.Tasks.Task.Factory.StartNew(() => methodToActivate(data));

数据项到达速度非常快(每秒、半秒等),因此创建了很多任务。处理每项任务可能需要大约一分钟。在测试它时,我看到线程数一直在增加。如何限制创建的任务数量,使实际工作线程的数量稳定高效。我的电脑只有双核。

谢谢!

【问题讨论】:

  • 数据一次到达多长时间?意思是,如果你现在得到一些数据,一秒钟后得到另一个数据,一秒钟后得到另一个数据,这样的循环运行多长时间?
  • 我问的原因是,如果您长时间每秒(或更快)接收数据,则 1 分钟的处理时间将不起作用。在这种情况下,您不能简单地将所有对象都扔到线程池中。相反,我会将所有对象放入一个队列(.NET 4.0 阻塞集合应该在这里工作),并启动一些线程来轮询该队列中的工作项。如果您 24/7 每秒获取数据,您将永远无法赶上。你确定你在这里做的事情是正确的吗?

标签: multithreading parallel-processing task-parallel-library


【解决方案1】:

您的一个问题是,默认调度程序会看到持续一分钟的任务,并假设它们被其他尚未执行的任务阻塞。为了尝试解除阻塞,它会安排更多待处理的任务,从而导致线程增长。您可以在这里做几件事:

  • 缩短您的任务(可能不是一种选择)。

  • 编写一个调度程序来处理这种情况并且不添加更多线程。

  • 使用 SetMaxThreads 防止 无限的线程池增长。

请参阅此处的线程注入部分:

http://msdn.microsoft.com/en-us/library/ff963549.aspx

【讨论】:

    【解决方案2】:

    您应该考虑在ConcurrentQueue<T> 周围使用the producer/consumer patternBlockingCollection<T>,在其中将BoundedCapacity 设置为考虑到您的工作负载特征的有意义的值。您可以使您的 BoundedCapacity 可配置,然后在运行一些分析会话时进行调整以找到最佳位置。

    虽然 TPL 确实会负责对您创建的任务进行排队,但创建太多任务并非没有惩罚。另外,产生的工作量超过你的消耗量有什么意义?您希望制作足够多的工作以使消费者永远不会挨饿,但您又不想远远领先于自己,因为这只会浪费资源并可能从消费者那里窃取同样的资源。

    【讨论】:

      【解决方案3】:

      您可以为 Task Parallel 库创建自定义 TaskScheduler,然后通过将其实例传递给 TaskFactory 构造函数来安排任务。

      这是一个如何做到这一点的示例:Task Scheduler with a maximum degree of parallelism

      【讨论】:

        猜你喜欢
        • 2013-02-10
        • 2020-03-15
        • 1970-01-01
        • 1970-01-01
        • 2012-01-02
        • 2011-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多