简体   繁体   English

在.net中将线程优先级从最低到最高

[英]Change thread priority from lowest to highest in .net

I am trying to speed things by having one thread write to a linked list and another thread process the linked list. 我试图通过让一个线程写入链表而另一个线程处理链表来加快速度。

For some reason if the method that writes to the linked list I make it into a task and the method that reads from the linked list a low priority thread the program finishes as a whole much faster. 出于某种原因,如果写入链表的方法我将其作为一个任务而从链表中读取一个低优先级线程的方法,程序整体上完成的速度要快得多。 In other words I experiense fastests results when doing: 换句话说,我在做的时候经历了紧固结果:

 Task.Factory.StartNew( AddItems );

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

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

Maybe because the first task is doing so much extra work than the other thread that's why everything as a whole will finish faster if I set the second method a low priority. 也许是因为第一个任务是做了比其他线程更多的额外工作,这就是为什么如果我将第二个方法设置为低优先级,整体上的所有内容都会更快完成。

Anyways now my question is The startProcessingItems runs with ThreadPriority = Lowest. 无论如何现在我的问题是 startProcessingItemsstartProcessingItems =最低运行。 How could I change it's priority to highest? 我怎么能把它的优先级改为最高? If I create a new Task in that method will it be running with low priority? 如果我在该方法中创建一个新任务,它将以低优先级运行吗? Basically the startProcessingItems ends with a list and once it has that list I will like to start executing with highest priority. 基本上,startProcessingItems以列表结束,一旦它具有该列表,我将开始以最高优先级执行。

This is not a good approach. 这不是一个好方法。 First off, LinkedList<T> is not thread safe, so writing to it and reading from it in two threads will cause race conditions. 首先, LinkedList<T>不是线程安全的,所以写入它并在两个线程中读取它将导致竞争条件。

A better approach would be to use BlockingCollection<T> . 更好的方法是使用BlockingCollection<T> This allows you to add items (producer thread) and read items (consumer thread) without worrying about thread safety, as it's completely thread safe. 这允许您添加项目(生产者线程)和读取项目(消费者线程),而不必担心线程安全,因为它完全是线程安全的。

The reading thread can just call blockingCollection.GetConsumingEnumerable() in a foreach to get the elements, and the write thread just adds them. 读取线程可以在foreach调用blockingCollection.GetConsumingEnumerable()来获取元素,而写入线程只是添加它们。 The reading thread will automatically block , so there's no need to mess with priorities. 读取线程将自动阻塞 ,因此不需要弄乱优先级。

When the writing thread is "done", you just call CompleteAdding , which will, in turn, allow the reading thread to finish automatically. 当写入线程“完成”时,您只需调用CompleteAdding ,这将允许读取线程自动完成。

You can improve the performance of your program by changing the inherent design, rather than by changing thread/process priorities. 您可以通过更改固有设计来改进程序的性能,而不是通过更改线程/进程优先级来提高程序的性能。

A big part of your problem is that you're doing a busywait: 你的问题很大一部分就是你正忙着做:

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

This results in it consuming lots of CPU cycles for no productive work, and it's why lowering it's priority makes it execute quicker. 这导致它消耗了大量的CPU周期而没有生产性工作,这就是为什么降低它的优先级使它更快地执行。 If you aren't busywaiting then that won't be an issue any more. 如果你没有忙着等待,那将不再是一个问题。

As Reed has suggested, BlockingCollection is tailor made for this situation. 正如里德建议的那样, BlockingCollection是针对这种情况量身定制的。 You can have a producer thread adding items using Add , and a consumer thread using Take knowing that the method will simply block if there are no more items to be removed. 您可以让生产者线程使用Add添加项目,使用Take消费者线程知道如果没有更多项目要删除,该方法将简单地阻止。

You can also store the Task you create and use Task.Result or Task.Wait to have the main thread wait for the other task to finish (without wasting CPU cycles). 您还可以存储您创建的Task ,并使用Task.ResultTask.Wait让主线程等待其他任务完成(不浪费CPU周期)。 (If you are using threads directly you can use Join .) (如果您直接使用线程,则可以使用Join 。)

In addition to what Reed and Servy have said: 除了里德和塞维所说的话:

Thread priority is relative to the processes priority. 线程优先级相对于进程优先级。

The Windows scheduler takes into account all other threads when it schedules time for threads. Windows调度程序在调度线程时间时会考虑所有其他线程。 Threads with higher priority take time away from other threads which could artificially slow down the rest of the system. 具有较高优先级的线程需要花费时间远离其他线程,这可能会人为地减慢系统的其余部分。 It's not like the system has no reason not to give you thread more priority. 这并不是说系统没有理由不给你更优先的线程。 The priority would only have an effect if something else took the CPU away from it--which happens for a reason. 如果其他东西让CPU远离它,优先级只会产生影响 - 这种情况发生了。 If nothing took the CPU away from the thread, it won't magically run faster with a priority of Highest. 如果没有任何东西使CPU远离线程,它将不会以优先级最高的方式神奇地运行。

Setting thread priority to Highest is almost always the wrong thing to do. 将线程优先级设置为Highest几乎总是错误的做法。

Likely the overhead of synchronization between the two threads will kill any performance gain you think you might get. 可能两个线程之间同步的开销会杀死您认为可能获得的任何性能提升。

Also, Thread.Sleep(0) only relinquishes time to threads of equal priority and is ready to run--which could lead to thread starvation. 此外,Thread.Sleep(0)只放弃具有相同优先级的线程的时间并准备好运行 - 这可能导致线程饥饿。 http://msdn.microsoft.com/en-us/library/d00bd51t(v=vs.80).aspx http://msdn.microsoft.com/en-us/library/d00bd51t(v=vs.80).aspx

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

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