简体   繁体   English

C#中的基本多线程问题

[英]Basic multi-threading questions in C#

I'm new to multithreading and I'm working on parallelizing an area in my application. 我是多线程的新手,我正在努力在我的应用程序中并行化一个区域。 I've read a number of posts on this site but I'm still confused as to the best way to approach my problem: 我在这个网站上看了很多帖子,但我仍然对解决问题的最佳方法感到困惑:

[1] In .NET 3.5, is ThreadPool the only way for a program to exploit the multi-cores in the machine ? [1]在.NET 3.5中, ThreadPool是程序利用机器中多核的唯一方法吗? ie Is it possible to spawn threads on different cores using new Thread() ? 即是否可以使用new Thread()在不同的核心上生成线程?

[2] My case: I have List<Calculation> that contains around 80 items, currently processed sequentially. [2]我的情况:我有List<Calculation>包含大约80个项目,目前按顺序处理。 So given that I'm using .NET 3.5 and based on what I've read, ThreadPool is probably my best bet for multithreading due to the high number of threads, however: 因此,鉴于我使用的是.NET 3.5并且基于我所阅读的内容,由于线程数量很多, ThreadPool可能是多线程的最佳选择:

  • There is a lot of dependency between the Calculations. 计算之间存在很多依赖关系。 Currently, the list is ordered in a way that all required Calculations are performed in the beginning. 目前,列表的排序方式是在开始时执行所有必需的计算。

This is how the dependency of the work items looks like (details not important, just wanted to make a point on the complexity of the dependencies): 这就是工作项的依赖性看起来如何(细节不重要,只是想要指出依赖项的复杂性):

替代文字

  • Calculation times are vastly different, one Calculation object might just involve retrieval of a value , other Calculation objects would involve a lot of work in nested loops...etc 计算时间差异很大,一个计算对象可能只涉及检索值,其他计算对象将涉及嵌套循环中的大量工作......等

How do I prioritize the main Calculations that have something like 10+ other work items depending on it ? 我如何根据它优先处理具有10多个其他工作项的主Calculations What is the most efficient way of signaling to use ? 使用信令的最有效方式是什么?

Thank you. 谢谢。

Edit: I should mention that List<Calculation> remains fixed. 编辑:我应该提到List<Calculation>仍然是固定的。 However, computing the 80+ calculations is called x million times. 但是,计算80+计算称为x百万次。 Every time an iterator is updated, Calculate() is invoked on every Calculation in the list. 每次更新迭代器时,都会在列表中的每个Calculation上调用Calculate()。

[1]: Yes, it is possible to spawn threads on different cores using new Thread() , although you might be better served using the threadpool. [1]:是的,可以使用new Thread()在不同的核心上生成线程,尽管使用new Thread()池可能会更好。 The differences are discussed here: 这里讨论的区别如下:

Thread vs ThreadPool 线程与ThreadPool

This would be SO MUCH EASIER in .Net 4.0 using Task Parallel Library . 使用任务并行库在.Net 4.0中这将是非常容易的。

When are you scheduled to upgrade? 你什么时候安排升级? It might be sooner than you could write all the required coordinating code yourself. 它可能比您自己编写所有必需的协调代码更快。

If you do have to do this brute force, you can use Thread.BeginThreadAffinity to ensure enclosed code runs on a single CPU. 如果您必须执行此强制操作,则可以使用Thread.BeginThreadAffinity来确保在单个CPU上运行封闭的代码。 This should help your calculation performance. 这应该有助于您的计算性能。

[1] In .NET 3.5, is ThreadPool the only way for a program to exploit the multi-cores in the machine ? [1]在.NET 3.5中,ThreadPool是程序利用机器中多核的唯一方法吗? ie Is it possible to spawn threads on different cores using new Thread() ? 即是否可以使用新的Thread()在不同的核心上生成线程?

It's up to the operating system to decide which core a thread should run on. 由操作系统决定一个线程应该运行在哪个核心上。 The OS will per default distribute threads evenly over multiple cores (at least in windows). 默认情况下,操作系统会在多个核心上均匀分配线程(至少在Windows中)。

ThreadPool are using the same kind of threads as the Thread class, as there really are only one kind (but different types of classes and algorithms wrapping them) ThreadPool使用与Thread类相同的线程,因为实际上只有一种(但不同类型的类和算法包装它们)

[2] My case: I have Listthat contains around 80 items, currently processed sequentially. [2]我的情况:我有Listthat包含大约80个项目,目前按顺序处理。 So given that I'm using .NET 3.5 and based on what I've read, ThreadPool is probably my best bet for multithreading due to the high number of threads, however: 因此,鉴于我使用的是.NET 3.5并且基于我所阅读的内容,由于线程数量很多,ThreadPool可能是多线程的最佳选择:

Using ThreadPool.QueueWorkItem seems to be the easiest way for you to convert your application. 使用ThreadPool.QueueWorkItem似乎是转换应用程序的最简单方法。

Keep in mind that running 100 different threads doesn't say that your application will be 10 times faster than running 10 threads. 请记住,运行100个不同的线程并不是说您的应用程序比运行10个线程快10倍。 It's more likely that 10 threads will run faster sine a lot if background stuff happens when .net and the OS switches between threads. 如果在.net和操作系统在线程之间切换时发生后台事件,那么10个线程更有可能运行得更快。

  1. I would convert the List into a Queue 我会将List转换为Queue
  2. When launching your calculations, add 10 (or any number you like) calls to ThreadPool.QueueWorkerItem(MyMethod); 启动计算时,将10个(或任何您喜欢的号码)调用添加到ThreadPool.QueueWorkerItem(MyMethod);
  3. In MyMethod, create a loop that continue to dequeue items from your queue until there are no more jobs left. 在MyMethod中,创建一个循环,继续将队列中的项目从队列中取出,直到没有剩余的作业为止。

As mentioned in the comments, PLINQ makes this very easy. 正如评论中所提到的, PLINQ使这很容易。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM