以低优先级运行或设置进程

IT *_*her 3 .net vb.net process

我正在尝试将进程作为低优先级运行.但我没有在ProcessPriorityClass中选择将其设置为低.但是,如果我去任务管理器,我可以手动将进程优先级设置为低.那怎么可以呢?我在下面的代码中将进程设置为低于正常优先级.

Dim s As New Process
s.StartInfo.FileName = "D:\myapp.exe"
s.Start()
s.PriorityClass = ProcessPriorityClass.BelowNormal
Run Code Online (Sandbox Code Playgroud)

Jon*_*nna 15

没有"低"值,但由于ProcessPriorityClass.Idle某种原因,默认任务管理器调用"低"(大多数其他任务管理器,如ProcessHacker或ProcessExplorer称之为"空闲"),如果你正在玩流程,你可能应该得到像ProcessHacker这样的体面的任务管理器替代品,而不是针对技术含量较低的用户的内置应用程序.

设置一个ProcessPriorityClass.Idle适合我的流程.

但需要注意的是:更改流程的优先级通常是一个坏主意,尤其是空闲和流程外部(至少从流程内部可以决定更改某些任务的优先级,然后再次把它放回去).

如果进程以不可共享的方式获取任何资源,那么设置这样的低优先级会导致严重的死锁,因为当任何更高优先级的进程需要时间片时它将不会运行(特别是在具有很少内核的机器上是残酷的)可用的同时时间片更少),因此如果更高优先级的进程也需要资源,它将永远等待获取它,因为优先级较低的进程将没有机会运行.

最终的Windows(虽然不是一些早期版本),将解决这个问题,通过暂时提高中的所有线程已经等待运行要高于低优先级的进程ThreadPriority.Highest中的线程ProcessPriorityClass.High过程,然后逐渐让他们失望下降到一个较低优先级,此时问题再次发生.

这可能与您想要发生的事情相反.

而且因为它在核心很少的机器上特别残酷,如果你的开发设备很强大,你可以在你的机器上运行一切正常的情况,然后用不那么强壮的机器的用户发现一切都停止了它们.

默认情况下,只有一些中断和"系统空闲进程"(这是一种特殊情况)在空闲时运行,这是有充分理由的.

尽管如此,如果你确定你知道自己在做什么(或者实际上,如果你正在尝试),那么s.PriorityClass = ProcessPriorityClass.Idle你想要的是什么.

编辑:更多关于优先事项:

给定线程相对于进程中的其他线程具有优先级,并且给定进程相对于系统上的其他进程具有优先级.

线程相对于系统上所有其他线程的优先级取决于这两者,如下表所示:

       Thread: | Idle | Lowest | Below  | Normal | Above  | Highest | Time-Critical
               |      |        | Normal |        | Normal |         | 
---------------+------+--------+--------+--------+--------+---------+--------------
Idle Process   |  1   |   2    |   3    |   4    |   5    |    6    |     15
Below-Normal   |  1   |   4    |   5    |   6    |   7    |    8    |     15
Normal Process |  1   |   6    |   7    |   8    |   9    |   10    |     15
Above-Normal   |  1   |   8    |   9    |  10    |  11    |   12    |     15
High Process   |  1   |  11    |  12    |  13    |  14    |   15    |     15
Realtime       | 16   |  22    |  23    |  24    |  25    |   26    |     31
Run Code Online (Sandbox Code Playgroud)

现在,任何给定的计算机都将具有X核心,其中当前的常见值为1,2,4,8或16.每个核心一次只能运行1个线程.

如果要运行的线程多于核心,则调度如下:

  1. 从存在的最高优先级线程开始.在它们之间共享核心.
  2. 如果线程多于核心,则在它们之间循环核心,因此该优先级的所有线程获得相等的份额.
  3. 如果剩下核心,则对下一个最高优先级的线程执行相同操作,依此类推.

因此,如果有4个核心,并且我们有3个线程优先级8(例如正常进程中的正常线程),2个优先级10(例如正常进程中的正常线程以上)和3个优先级6(空闲进程中的最高优先级线程) )然后他们都准备好了:

  1. 2个优先级10个线程总是在核心上获得时间片.
  2. 其余2个核心将在3个普通/正常线程之间进行分时.
  3. 3个优先级6个线程将无法运行.

这对于那3个线程来说是坏的,但它对整个系统来说应该是好的,因为这3个线程应该只用于那些重要性很低的东西,以至于我们完全可以不运行它们.

这些数字也通过以下方式得到提升:

  1. 如果正常进程拥有前景窗口,则前景增强开启(桌面正常,服务器不正常),它会提升到高于正常进程的情况.
  2. 当窗口接收鼠标,键盘或计时器输入或来自另一个窗口的消息时,其进程将暂时提升.
  3. 如果某个线程正在等待某个东西,并且该东西已经准备就绪,那么它就会得到提升.
  4. 如果一个线程已经准备好很长时间没有运行,它可能会随机获得一个很大的提升.

前三个应该是合理的常识,因为很明显为什么人们可能希望这些进程或线程得到提升.

第四个是引入一个温和的问题来解决一个严重的问题:如果线程A需要资源低优先级线程B,并且只有一个核可用,那么它们将死锁,因为线程B不会获得时间片,所以它不会释放资源,因此线程A将继续尝试获取它,因此它不会结束,因此线程B将不会获得时间片...

所以操作系统将线程B提升为临时超高优先级,并且线程A不会查看一点,并且在它与死锁之间的初始减速之间,整个系统比它慢得多应该是(拥有一个多核系统的实际优势之一并不是它让很多忙碌的进程能够更好地协同工作,但这使得这种情况不太可能发生).

所有这一切的后果是99%的时间,线程的最佳优先级是正常的,并且进程的最佳优先级是正常的.

空闲/低落应保留在如此无足轻重的过程中,如果他们从未有机会做某事我们真的不在乎.屏幕保护程序确实是一个例子,因为如果屏幕保护程序永远不会有机会运行,它可能不应该; 没有人花费大量资金在最先进的钻井平台上观看飞行烤面包机(尽管在20世纪90年代,人们可能会想到).

非常规优先级的例子做得很好:

"不要那样做"建议的问题在于它总是不完整的; 有很多事情,"不要那样做"一般是最好的建议(例如,弄乱GC会是另一个例子)但是,如果不理解"不这样做",为什么"不这样做"是好建议例外,事实上它并不是真正好的建议,除非你涵盖例外,它只是教条.因此,值得考虑高优先级和低优先级的良好案例,以及它们如何消除所涉及的问题.

实时媒体的实时处理.

如果您正在处理现场音乐或视频,并且需要专业输出(您实际上正在为其他人录制或传输此内容,而不是仅仅在您自己的计算机上观看它),那么在运行该节目的线程中执行此操作是有意义的.最高优先级 - 可能将流程设置为实时.这会对整个系统造成不利影响,但那时机器上最重要的事情就是进行媒体处理的过程,并且考虑到媒体流遭遇故障的选择,以及导致系统严重问题的事情,你'相反,系统会发生严重问题并在以后处理."与其他进程很好地协同工作"的所有常规概念都不在桌面上,实际上在*nix系统上用于此类目的,这种工作通常使用实时内核来完成,该内核针对不太好的成本进行了优化,以实现可预测的时间.整体并发性能(尽管上面的所有其他细节也会有所不同,我只解释了上面的Windows方式).

.NET中的Finaliser线程

.NET中的终结器线程以高优先级运行.大多数时候这个线程无关,所以它不活跃.当它确实有事情要做(终结队列不是空的)时,无论有多少其他线程在运行,它都是非常重要的.一些重要的说明:

  1. 任何写得很好的终结者都应该快速执行,因此处理所有终结者所花费的总时间应该很短.(最终确定,如果需要很长时间,甚至可能在某些情况下被放弃).
  2. 任何写得很好的终结者都不应该干扰其他线程,因此处理所有终结者不应该干扰其他线程.

这两个事实对于最小化具有高于正常优先级的线程的缺点很重要,因为它们意味着它没有进入优先级反转问题,并且在大多数情况下没有运行,因此没有与之竞争其他线程.

系统空闲过程

在空闲状态下运行特殊进程有两个目标.第一个是因为总是有一个进程在空闲状态下运行,每个核心都有一个线程,所以没有必要让调度程序有任何代码来处理没有线程运行的情况,因为总有这样一个线程,如果没有其他线程,上面描述的逻辑将运行其中一个线程.

第二个是这些线程可以调用核心具有的任何节能或降频能力,因为如果它们运行了任何时间长度,那么根据定义,不需要CPU并且应该将其置于低功耗状态.

重要的是,此过程永远不会获得另一个进程可能需要的任何不可共享资源,因此它永远不会导致优先级反转问题.

在这里我们可以看到,该过程的目的意味着我们几乎从不希望它运行,如果有任何其他线程有任何事情要做.

(它还为我们提供了一个很好的衡量标准,以确定什么时候应该处于低优先级;如果它不应该与存在的只是将CPU置于低功耗状态的线程竞争,那么它不应该是低优先级) .