我试图通过让一个线程写入链表而另一个线程处理链表来加快速度。
由于某种原因,如果写入链接列表的方法我将其作为一个任务而从链接列表中读取一个低优先级线程的方法,则程序整体上完成得更快。换句话说,我在做的时候经历了紧固结果:
Task.Factory.StartNew( AddItems );
new Thread( startProcessingItems ) { Priority = ThreadPriority.Lowest }.Start();
while(completed==false)
Thread.Sleep(0);
也许是因为第一个任务是做了比其他线程更多的额外工作,这就是为什么如果我将第二个方法设置为低优先级,整个事情将会更快完成。
无论如何现在我的问题是 startProcessingItems
以ThreadPriority =最低运行。我怎么能把它的优先级改为最高?如果我在该方法中创建一个新任务,它将以低优先级运行吗?基本上,startProcessingItems以列表结束,一旦它具有该列表,我将开始以最高优先级执行。
答案 0 :(得分:5)
这不是一个好方法。首先,LinkedList<T>
不是线程安全的,所以写入它并在两个线程中读取它将导致竞争条件。
更好的方法是使用BlockingCollection<T>
。这允许您添加项目(生产者线程)和读取项目(消费者线程),而不必担心线程安全,因为它完全是线程安全的。
读取线程只需调用blockingCollection.GetConsumingEnumerable()
中的foreach
来获取元素,写入线程就可以添加它们。阅读线程将自动阻止,因此无需乱搞优先级。
当写作线程“完成”时,你只需调用CompleteAdding
,这将允许阅读线程自动完成。
答案 1 :(得分:2)
您可以通过更改固有设计来改进程序的性能,而不是通过更改线程/进程优先级来提高程序性能。
你的问题很大一部分就是你正忙着做:
while(completed==false)
Thread.Sleep(0);
这导致它消耗大量的CPU周期而没有生产性工作,这就是为什么降低它的优先级使它更快地执行。如果你不忙,那么这将不再是一个问题。
正如里德所说,BlockingCollection
是针对这种情况量身定做的。您可以让生产者线程使用Add
添加项目,使用Take
使用消费者线程,知道如果没有更多项目要删除,该方法将会阻止。
您还可以存储您创建的Task
并使用Task.Result
或Task.Wait
让主线程等待其他任务完成(不浪费CPU周期)。 (如果您直接使用线程,则可以使用Join
。)
答案 2 :(得分:2)
除了里德和塞维所说的话:
线程优先级相对于进程优先级。
Windows调度程序在调度线程时间时会考虑所有其他线程。具有较高优先级的线程需要花费时间远离其他线程,这可能会人为地减慢系统的其余部分。这并不是说系统没有理由不给你更优先的线程。如果其他东西让CPU远离它,优先级只会产生影响 - 这种情况发生了。如果没有任何东西使CPU远离线程,它将不会以优先级最高的方式神奇地运行得更快。
将线程优先级设置为Highest几乎总是错误的。
两个线程之间的同步开销可能会扼杀您认为可能获得的任何性能提升。
此外,Thread.Sleep(0)仅将时间放弃到具有相同优先级的线程并准备好运行 - 这可能导致线程不足。 http://msdn.microsoft.com/en-us/library/d00bd51t(v=vs.80).aspx