C#中的基本多线程问题

时间:2010-11-04 17:54:00

标签: c# multithreading threadpool worker-thread

我是多线程的新手,我正在努力在我的应用程序中并行化一个区域。我在这个网站上看了很多帖子,但我仍然对解决问题的最佳方法感到困惑:

[1]在.NET 3.5中,ThreadPool是程序在机器中利用多核的唯一方法吗?即是否可以使用new Thread()

在不同的核心上生成线程

[2]我的情况:我的List<Calculation>包含大约80个项目,目前按顺序处理。因此,鉴于我使用的是.NET 3.5并且基于我所阅读的内容,ThreadPool可能是多线程的最佳选择,因为线程数量很多,但是:

  • 计算之间存在很多依赖关系。目前,该列表的排序方式是在开始时执行所有必需的计算。

这就是工作项的依赖关系的样子(细节并不重要,只是想要指出依赖项的复杂性):

alt text

  • 计算时间差别很大,一个计算对象可能只涉及检索值,其他计算对象将涉及嵌套循环中的大量工作......等等。

如何根据具有10多个其他工作项目的主Calculations的优先顺序排列?使用信令的最有效方式是什么?

谢谢。

编辑:我应该提到List<Calculation>仍然是固定的。但是,计算80+计算称为x百万次。每次更新迭代器时,都会在列表中的每个Calculation上调用Calculate()。

4 个答案:

答案 0 :(得分:2)

[1]:是的,可以使用new Thread()在不同的核心上生成线程,尽管使用线程池可能会更好。这里讨论了不同之处:

Thread vs ThreadPool

答案 1 :(得分:2)

使用Task Parallel Library在.Net 4.0中这将更加轻松。

您计划何时升级?它可能比您自己编写所有必需的协调代码更快。

如果您必须执行此强制操作,则可以使用Thread.BeginThreadAffinity确保在单个CPU上运行封闭的代码。这应该有助于您的计算性能。

答案 2 :(得分:1)

  

[1]在.NET 3.5中,ThreadPool是程序利用机器中多核的唯一方法吗?即是否可以使用新的Thread()?

在不同的核心上生成线程

由操作系统决定线程应该在哪个核心上运行。默认情况下,操作系统会在多个核心上均匀分配线程(至少在Windows中)。

ThreadPool使用与Thread类相同的线程,因为实际上只有一种(但不同类型的类和算法包装它们)

  

[2]我的情况:我有Listthat包含大约80个项目,目前按顺序处理。因此,鉴于我使用的是.NET 3.5并且基于我所阅读的内容,由于线程数量很多,ThreadPool可能是多线程的最佳选择:

使用ThreadPool.QueueWorkItem似乎是转换应用程序的最简单方法。

请记住,运行100个不同的线程并不是说您的应用程序比运行10个线程快10倍。如果在.net和操作系统在线程之间切换时发生后台事件,那么10个线程更有可能运行得更快。

  1. 我会将List转换为Queue
  2. 启动计算时,将10个(或任何您喜欢的号码)调用添加到ThreadPool.QueueWorkerItem(MyMethod);
  3. 在MyMethod中,创建一个循环,继续将队列中的项目从队列中取出,直到没有剩余的作业为止。

答案 3 :(得分:0)

正如评论中所提到的,PLINQ使这很容易。

List<Calculation> foo = ...;
foo.AsParallel.Select(c => c.Calculate());