2

我试图通过让一个线程写入链接列表而另一个线程处理链接列表来加快速度。

出于某种原因,如果写入链表的方法我将它变成一个任务,而从链表读取的方法是一个低优先级线程,则程序整体完成的速度要快得多。换句话说,我在执行以下操作时会体验到最快的结果:

 Task.Factory.StartNew( AddItems );

 new Thread( startProcessingItems ) { Priority = ThreadPriority.Lowest }.Start();

 while(completed==false)
    Thread.Sleep(0);

也许是因为第一个任务比另一个线程做了更多的工作,这就是为什么如果我将第二个方法设置为低优先级,所有事情作为一个整体都会更快地完成。

无论如何,现在我的问题是startProcessingItemsThreadPriority = Lowest的运行。我怎样才能将它的优先级更改为最高?如果我在该方法中创建一个新任务,它会以低优先级运行吗?基本上 startProcessingItems 以一个列表结束,一旦它有了这个列表,我就会以最高优先级开始执行。

4

3 回答 3

5

这不是一个好方法。首先,LinkedList<T>它不是线程安全的,因此在两个线程中写入和读取它会导致竞争条件。

更好的方法是使用BlockingCollection<T>. 这允许您添加项目(生产者线程)和读取项目(消费者线程)而不用担心线程安全,因为它是完全线程安全的。

读取线程可以调用blockingCollection.GetConsumingEnumerable()aforeach来获取元素,而写入线程只是添加它们。读取线程会自动阻塞,所以没有必要搞乱优先级。

当写入线程“完成”时,您只需调用CompleteAdding,这将反过来允许读取线程自动完成。

于 2012-09-20T19:14:16.477 回答
2

您可以通过更改固有设计而不是更改线程/进程优先级来提高程序的性能。

您的问题的很大一部分是您正在忙着等待:

while(completed==false)
    Thread.Sleep(0);

这导致它消耗大量 CPU 周期而没有生产性工作,这就是为什么降低它的优先级使其执行得更快的原因。如果您不忙于等待,那么这将不再是问题。

正如 Reed 所建议的,BlockingCollection它是为这种情况量身定做的。您可以让生产者线程使用 来添加项目Add,而消费者线程使用Take知道如果没有更多项目要删除,该方法将简单地阻塞。

您还可以存储Task您创建和使用的内容,Task.Result或者Task.Wait让主线程等待其他任务完成(不浪费 CPU 周期)。(如果您直接使用线程,则可以使用Join。)

于 2012-09-20T19:17:32.997 回答
2

除了 Reed 和 Servy 所说的:

线程优先级与进程优先级相关。

Windows 调度程序在调度线程时间时会考虑所有其他线程。具有较高优先级的线程会占用其他线程的时间,这可能会人为地减慢系统的其余部分。这并不是说系统没有理由不给你线程更多的优先级。优先级只有在其他东西将 CPU 带离它时才会产生影响——这是有原因的。如果没有任何东西将 CPU 带离线程,它不会神奇地以最高优先级运行得更快。

将线程优先级设置为最高几乎总是错误的做法。

两个线程之间的同步开销可能会扼杀您认为可能获得的任何性能提升。

此外,Thread.Sleep(0) 仅将时间分配给具有相同优先级的线程并准备好运行——这可能导致线程饥饿。 http://msdn.microsoft.com/en-us/library/d00bd51t(v=vs.80).aspx

于 2012-09-20T19:20:29.163 回答