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

时间:2014-01-25 13:16:09

标签: .net vb.net process

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

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

2 个答案:

答案 0 :(得分:14)

没有"低"值,虽然有ProcessPriorityClass.Idle由于某种原因,默认任务管理员调用"低" (像ProcessHacker或ProcessExplorer这样的大多数其他任务管理员都会调用它"空闲",如果你正在玩流程,你应该得到一个像ProcessHacker那样体面的任务管理器替换,而不是内置的应用程序针对技术含量较低的用户。)

将流程设置为ProcessPriorityClass.Idle对我来说很好。

但需要注意的是:改变流程的优先级通常是一个坏主意,尤其是闲置和流程外部(至少从流程内部可以决定更改流程)某些任务的优先级更高,然后重新设置。)

如果进程以不可共享的方式获取任何资源,那么设置这样的低优先级会导致严重的死锁,因为它不会在任何优先级较高的进程需要时间片时运行(特别是在几乎没有时间的计算机上是残酷的)核心,因为可用的同步时间片数较少),因此如果优先级较高的进程也需要资源,它将永远等待获得它,因为优先级较低的进程没有机会运行。 / p>

最终,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

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

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

  1. 从存在的最高优先级线程开始。在它们之间共享核心。
  2. 如果线程多于核心,则在它们之间循环核心,因此该优先级的所有线程获得相同的份额。
  3. 如果剩下核心,请对下一个最高优先级的线程执行相同操作,依此类推。
  4. 所以,如果有4个核心,我们有3个线程优先级8(例如正常进程中的正常线程),2个优先级10(例如正常进程中的正常线程)和3个优先级6(高优先级线程)一个空闲的过程)然后他们都准备好了:

    1. 2个优先级10个线程总是会在核心上获得时间片。
    2. 其余2个核心将在3个正常/正常线程之间分时。
    3. 3个优先级6个线程将无法运行。
    4. 对于这3个线程来说这是不好的,但应该对整个系统都有好处,因为这3个线程应该仅用于那些重要性低的东西,而不是我们这样做的。他们没有跑步,完全没事。

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

      1. 如果正常进程拥有前景窗口,则前景增强开启(桌面正常,服务器不正常),它会提升到高于正常进程的范围。
      2. 当一个窗口接收鼠标,键盘或计时器输入或来自另一个窗口的消息时,它的过程会暂时提升。
      3. 如果某个帖子正在等待某个东西,并且该东西已经准备就绪,那么它就会得到提升。
      4. 如果一个线程已经准备好很长时间而没有运行,它可能会随机获得一个很大的提升。
      5. 前三个应该是合理的常识,因为很明显为什么人们可能希望这些流程或线程得到提升。

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

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

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

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

        非正常优先事项的例子很好:

        问题&#34;不要这样做&#34;建议,是它总是不完整的;有很多事情不会做到这一点&#34;一般来说是最好的建议(例如,弄乱GC会是另一个例子),但是人们不能真正理解为什么不做那些&#34;不要做那个&#34;在不了解例外情况的情况下提出好的建议,除非你涵盖例外,否则它确实不是很好的建议,它只是教条。因此,值得考虑高优先级和低优先级的优秀案例,以及它们如何消除所涉及的问题。

        实时媒体的实时处理。

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

        .NET中的Finaliser线程

        .NET中的终结者线程以高优先级运行。大多数时候这个线程无关,所以它不活跃。当它确实有事情要做(终结队列不是空的)时,无论有多少其他线程在运行,它都能做到这一点至关重要。一些重要的注意事项:

        1. 任何写得很好的终结者都应该快速执行,因此处理所有终结者所花费的总时间应该很短。 (最终确定,如果需要很长时间,甚至可能在某些情况下被放弃)。
        2. 任何写得很好的终结者都不应该干涉其他线程,因此处理所有终结者不应该干扰其他线程。
        3. 这两个事实对于最大限度地减少高于正常优先级线程的缺点很重要,因为它们意味着它不会进入优先级反转问题,而且大部分时间都没有运行因此不与其他线程竞争。

          系统空闲流程

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

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

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

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

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

答案 1 :(得分:2)

我猜ProcessPriorityClass.Idle在任务管理员中意味着“低”。

另请参阅:ProcessPriorityClass-Enumeration