3

我是多线程的新手,我正在处理我的应用程序中的一个区域。我已经阅读了该网站上的许多帖子,但我仍然对解决问题的最佳方法感到困惑:

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

[2] 我的案例:我有List<Calculation>大约 80 个项目,目前按顺序处理。因此,鉴于我正在使用 .NET 3.5 并且根据我所读到的内容,ThreadPool由于线程数量众多,这可能是我对多线程的最佳选择,但是:

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

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

替代文字

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

我如何Calculations根据它确定具有 10 多个其他工作项的主要内容的优先级?什么是最有效的信号使用方式?

谢谢你。

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

4

4 回答 4

2

[1]:是的,可以使用 来在不同的内核上生成线程new Thread(),尽管使用线程池可能会更好地为您服务。此处讨论了差异:

线程与线程池

于 2010-11-04T18:07:49.183 回答
2

这在 .Net 4.0 中使用Task Parallel Library会容易得多。

你计划什么时候升级?这可能比您自己编写所有必需的协调代码要快。

如果你必须这样做,你可以使用Thread.BeginThreadAffinity来确保封闭的代码在单个 CPU 上运行。这应该有助于您的计算性能。

于 2010-11-04T18:07:59.077 回答
1

[1] 在 .NET 3.5 中,线程池是程序利用机器中多核的唯一方法吗?即是否可以使用 new Thread() 在不同的内核上生成线程?

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

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

[2] 我的案例:我的 List 包含大约 80 个项目,目前按顺序处理。因此,鉴于我正在使用 .NET 3.5 并且根据我所读到的内容,由于线程数量众多,ThreadPool 可能是我最好的多线程选择,但是:

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

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

  1. 我会将其转换ListQueue
  2. 启动计算时,向 ThreadPool.QueueWorkerItem(MyMethod); 添加 10 个(或您喜欢的任何数量)调用;
  3. 在 MyMethod 中,创建一个循环,继续从队列中取出项目,直到没有更多作业。
于 2010-11-04T18:20:40.607 回答
0

正如评论中提到的,PLINQ使这非常容易。

List<Calculation> foo = ...;
foo.AsParallel.Select(c => c.Calculate());
于 2010-11-04T18:09:11.087 回答