vb.net 以低优先级运行或设置进程
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21351045/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Run or set a process in low priority
提问by IT researcher
I am trying to run a process as Low priority. but I didn't get option in ProcessPriorityClass to set it to low. But if I go to task manager I can set a process priority to low manually. So how It can be done? Below code I used to set process to below normal priority.
我正在尝试以低优先级运行进程。但我没有在 ProcessPriorityClass 中获得将其设置为低的选项。但是如果我去任务管理器,我可以手动将进程优先级设置为低。那么如何做到呢?下面的代码我用来将进程设置为低于正常优先级。
Dim s As New Process
s.StartInfo.FileName = "D:\myapp.exe"
s.Start()
s.PriorityClass = ProcessPriorityClass.BelowNormal
回答by Jon Hanna
There is no "Low" value, though there is ProcessPriorityClass.Idlethat for some reason the default taskmanager calls "Low" (most other task managers like ProcessHacker or ProcessExplorer call it "Idle", and if you're playing about with processes, you should probably get a decent task manager replacement like ProcessHacker, rather than the built-in app aimed at less-technical users).
没有“低”值,尽管ProcessPriorityClass.Idle出于某种原因,默认任务管理器调用“低”(大多数其他任务管理器,如 ProcessHacker 或 ProcessExplorer 称其为“空闲”,如果您正在处理进程,您可能应该获得像ProcessHacker这样像样的任务管理器替代品,而不是针对技术含量较低的用户的内置应用程序)。
Setting a process to ProcessPriorityClass.Idleworks fine for me.
设置一个过程ProcessPriorityClass.Idle对我来说很好用。
A note of caution though: it's generally a bad idea to change a priority class of a process, and most especially to idle and from outside the process (at least from inside the process you can decide to change the priority higher for certain tasks, then set it back again).
但请注意:更改进程的优先级通常是一个坏主意,尤其是在空闲和进程外部(至少从进程内部,您可以决定将某些任务的优先级更改为更高,然后重新设置回来)。
Setting such a low priority can cause nasty deadlocks if the process obtains any resource in a non-sharable manner, because it won't run while any higher-priority process needs a time slice (especially brutal on machines with few cores, as there are fewer simultaneous time slices available), so if a higher priority process also needs a resource, it will be waiting forever to get it, because the lower-priority process won't have a chance to run.
如果进程以不可共享的方式获取任何资源,设置如此低的优先级会导致严重的死锁,因为当任何更高优先级的进程需要时间片时它不会运行(尤其是在内核较少的机器上,因为有更少的同时可用时间片),因此如果更高优先级的进程也需要资源,它将永远等待获取资源,因为低优先级进程将没有机会运行。
Eventually, Windows (though not some of the earlier versions) will fix that by temporarily boosting all the threads in the lower priority process that have been waiting to run to be higher than ThreadPriority.Highestthreads in ProcessPriorityClass.Highprocesses, and then gradually let them fall down to a lower priority, at which point the problem happens again.
最终,Windows(虽然不是一些早期版本)将通过暂时将等待运行的低优先级进程中的所有线程提升到高于进程中的ThreadPriority.Highest线程ProcessPriorityClass.High,然后逐渐让它们降到更低的级别来解决这个问题。优先级,此时问题再次发生。
This is probably the opposite to what you want to have happen.
这可能与您希望发生的情况相反。
And because it's especially brutal on machines with few cores, if your development rig is beefy you can have the situation where everything works fine on your machine, and then users with less beefy machines find that everything grinds to a halt for them.
而且因为它在内核很少的机器上尤其残酷,如果你的开发设备很强大,你可能会遇到这样的情况,在你的机器上一切正常,然后使用不太强大的机器的用户发现一切对他们来说都停止了。
By default, only some interrupts and the "System Idle Process" (which is a special case) runs at Idle, and there's a good reason for that.
默认情况下,只有一些中断和“系统空闲进程”(这是一种特殊情况)在空闲时运行,这是有充分理由的。
Still, if you are sure you know what you are doing (or indeed, if you're experimenting), then s.PriorityClass = ProcessPriorityClass.Idleis what you want.
尽管如此,如果您确定自己知道自己在做什么(或者确实,如果您正在试验),那么s.PriorityClass = ProcessPriorityClass.Idle这就是您想要的。
Edit: A bit more about priorities:
编辑:关于优先级的更多信息:
A given thread has a priority, relative to other threads in the process, and a given process has a priority relative to other processes on the system.
给定线程相对于进程中的其他线程具有优先级,并且给定进程相对于系统上的其他进程具有优先级。
The priority of a thread relative to all other threads on the system, depends on both of these, as per the following table:
线程相对于系统上所有其他线程的优先级取决于这两者,如下表所示:
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
Now, any given computer will have X cores, where common values today are 1, 2, 4, 8 or 16. There can only be 1 thread per core running at a time.
现在,任何给定的计算机都将有 X 个内核,其中今天的常见值为 1、2、4、8 或 16。每个内核一次只能运行 1 个线程。
If there are more threads that want to run than there are cores, then the scheduling happens as follows:
如果要运行的线程数多于内核数,则调度过程如下:
- Start with the highest priority threads that exist. Share out cores between them.
- If there were more threads than cores, round-robin the cores between them, so all threads of that priority get an equal share.
- If there are cores left over, do the same with the next highest priority threads, and so on.
- 从存在的最高优先级线程开始。在它们之间共享核心。
- 如果线程数多于内核数,则在它们之间循环使用内核数,因此该优先级的所有线程都获得相等的份额。
- 如果有剩余的内核,则对下一个优先级最高的线程执行相同操作,依此类推。
So, if there were 4 cores, and we had 3 threads priority 8 (e.g. normal threads in normal processes), 2 priority 10 (e.g. above-normal threads in normal processes) and 3 priority 6 (highest-priority thread in an idle process) and they were all ready to run then:
因此,如果有 4 个内核,并且我们有 3 个线程优先级为 8(例如,正常进程中的正常线程)、2 个优先级为 10(例如,正常进程中的高于正常线程)和 3 个优先级为 6(空闲进程中的最高优先级线程) ),然后他们都准备好运行了:
- The 2 priority 10 threads would always get a timeslice on a core.
- The remaining 2 cores would be time-shared between the 3 normal/normal threads.
- The 3 priority 6 threads will not get a chance to run.
- 2 个优先级为 10 的线程将始终在核心上获得一个时间片。
- 其余 2 个内核将在 3 个正常/正常线程之间分时共享。
- 3 优先级 6 线程将没有机会运行。
This is bad for those 3 threads, but it shouldbe good for the system as a whole, because those 3 threads should only be for things that are of such low importance that we're totally okay with them not running.
这对那 3 个线程不利,但对整个系统来说应该是好事,因为这 3 个线程应该只用于那些重要性低到我们完全可以不运行它们的事情。
These numbers are also boosted in the following ways:
这些数字还通过以下方式得到提升:
- With foreground boost on (normal for desktop, not normal for server) if a normal process owns the foreground window, it is boosted above normal processes that do not.
- When a window receives mouse, keyboard or timer input, or a message from another window, its process is given a temporary boost.
- If a thread is waiting on something, and that thing has become ready, it gets a boost.
- If a thread has been ready for a long time without running, it may randomly get a large boost.
- 启用前台提升(桌面正常,服务器不正常)如果正常进程拥有前台窗口,它会被提升到没有的正常进程之上。
- 当一个窗口接收到鼠标、键盘或定时器输入,或者来自另一个窗口的消息时,它的进程会被暂时提升。
- 如果一个线程正在等待某个东西,而那个东西已经准备好了,它就会得到提升。
- 如果一个线程已经准备好很长时间没有运行,它可能会随机得到一个很大的提升。
The first three of these should be reasonably common sense, in that it's obvious why one might want those processes or threads to be boosted.
前三个应该是合理的常识,因为很明显为什么人们可能希望提升这些进程或线程。
The fourth is introducing a mild problem to fix a severe problem: If thread A needs resource low-priority thread B has, and there is only one core available, then they will dead-lock because thread B won't get a time-slice, so it won't release the resource so thread A will keep trying to get it so it won't end so thread B won't get a time-slice...
第四是引入一个轻微的问题来解决一个严重的问题:如果线程 A 需要低优先级线程 B 拥有的资源,并且只有一个内核可用,那么它们将死锁,因为线程 B 不会得到时间片,因此它不会释放资源,因此线程 A 将继续尝试获取它,因此它不会结束,因此线程 B 不会获得时间片...
So the OS boosts thread B to be temporarily super-high priority, and thread A doesn't get a look in for a bit, and between that and the initial slow-down from the deadlock the system as a whole is much slower than it should be (one of the practical advantages of having a multi-core system isn't so much that it lets lots of busy processes work together better, but that it makes this scenario much less likely to happen).
因此,操作系统将线程 B 提升为暂时的超高优先级,而线程 A 没有得到任何关注,并且在这与死锁的初始减速之间,整个系统比它慢得多应该是(拥有多核系统的实际优势之一并不是它可以让许多繁忙的进程更好地协同工作,而是使这种情况不太可能发生)。
The consequences of all of this is that 99% of the time, the best priority for a thread is normal, and the best priority for a process is normal.
所有这一切的结果是,在 99% 的时间里,线程的最佳优先级是正常的,而进程的最佳优先级是正常的。
Idle/Low should be preserved for processes of such insignificance that we really don't care if they never get a chance to do something. Screen-savers are indeed an example, because if a screen-saver never gets a chance to run, it probably shouldn't; nobody spends a lot of money on a state-of-the-art rig just to watch flying toasters (though during the 1990s one might have wondered).
Idle/Low 应该保留用于如此微不足道的进程,以至于我们真的不在乎它们是否永远没有机会做某事。屏幕保护程序确实是一个例子,因为如果屏幕保护程序永远没有机会运行,它可能不应该;没有人会为了观看飞行烤面包机而在最先进的装备上花费大量资金(尽管在 1990 年代,人们可能会想知道)。
Examples of non-normal priority done well:
非正常优先级做得很好的例子:
The problem with "don't do that" advice, is that it's always incomplete; there are plenty of things where "don't do that" is the best advice generally (e.g. messing with the GC would be another example) but one can't really grok why "don't do that" is good advice without understanding the exceptions, and indeed it's not really good advice unless you cover the exceptions, it's just dogma. So it's worth considering good cases of high and low priority, and what about them removes the problem involved.
“不要那样做”建议的问题在于它总是不完整的;有很多事情,“不要那样做”通常是最好的建议(例如,搞乱 GC 将是另一个例子),但是如果不理解为什么“不要那样做”是好的建议,就无法真正理解例外,事实上,除非你涵盖例外,否则这不是很好的建议,这只是教条。所以值得考虑高优先级和低优先级的好案例,它们如何消除所涉及的问题。
Realtime processing of live media.
实时处理实时媒体。
If you are processing live music or video, and need a professional output (you are actually recording or transmitting this for others, rather than just watching it on your own machine), then it makes sense to do this in threads that are running at the very highest priorities—perhaps with the process set to realtime. This penalises the entire system as a whole, but right then the most important thing on that machine is the process doing the media processing, and given the choice of the media stream suffering a glitch, and something causing serious problems to the system, you'd rather have serious problem happen to the system and deal with it later. All normal concepts of "playing nicely with other processes" are off the table, and indeed on *nix systems for such purposes this sort of work is often done with a real-time kernel that is optimised for predictable time at the cost of less good overall concurrent performance (though all the other details above will differ too, I've only explained the Windows way above).
如果您正在处理现场音乐或视频,并且需要专业的输出(您实际上是在为他人录制或传输这些内容,而不仅仅是在您自己的机器上观看),那么在运行的线程中执行此操作是有意义的非常高的优先级——也许将流程设置为实时。这会惩罚整个系统作为一个整体,但此时该机器上最重要的事情是进行媒体处理的过程,并且考虑到媒体流的选择出现故障,以及对系统造成严重问题的某些事情,您宁愿系统发生严重问题,稍后再处理。“与其他进程很好地合作”的所有正常概念都被排除在外,
Finaliser thread in .NET
.NET 中的终结器线程
The finaliser thread in .NET runs at high priority. Most of the time this thread has nothing to do, so it is not active. When it does have something to do (the finalisation queue is not empty), then it's vitally important that it does it no matter how many other threads are running. Some important notes:
.NET 中的终结器线程以高优先级运行。大多数时候这个线程没有任何关系,所以它是不活跃的。当它确实有事情要做时(终结队列不为空),那么无论有多少其他线程正在运行,它都会做这件事至关重要。一些重要的注意事项:
- Any well-written finaliser should be fast to execute, so the total time spent processing all finalisers should be short. (Finalisation and may even be abandoned in some circumstances if it takes a long time).
- Any well-written finaliser should not interfere with other threads, and hence processing all finalisers should not interfere with other threads.
- 任何编写良好的终结器都应该能够快速执行,因此处理所有终结器所花费的总时间应该很短。(最终定稿,在某些情况下,如果需要很长时间甚至可能会被放弃)。
- 任何编写良好的终结器都不应干扰其他线程,因此处理所有终结器不应干扰其他线程。
These two facts are important in minimising the downside of having a higher-than-normal priority thread, since they mean it doesn't get into priority inversion problems, and for most of the time isn't running and hence isn't competing with other threads.
这两个事实对于最小化具有高于正常优先级的线程的不利影响很重要,因为它们意味着它不会陷入优先级反转问题,并且大部分时间都没有运行,因此不会与其他线程。
The System Idle Process
系统空闲进程
Having a special process running at idle serves two goals. The first is that since there is always a process running at idle that has a thread per core, there is no need for the scheduler to have any code to deal with the case of there being no thread to run, because there is always such a thread, and the logic described above will run one of those threads if there are no others.
让一个特殊的进程在空闲状态下运行有两个目的。第一个是因为总是有一个进程在空闲状态运行,每个内核都有一个线程,调度器不需要任何代码来处理没有线程运行的情况,因为总是有这样的线程,如果没有其他线程,上述逻辑将运行其中一个线程。
The second is that these threads can call into whatever power-saving or underclocking abilities the core has, because if they are running for any length of time, then by definition the CPU is not needed and should be put into a low-power state.
第二个是这些线程可以调用内核具有的任何节能或降频功能,因为如果它们运行任何时间长度,那么根据定义,CPU 就不需要,应该进入低功耗状态。
Importantly, this process never obtains any non-shareable resource another process might want, so it can never cause priority inversion problems.
重要的是,这个进程永远不会获得另一个进程可能想要的任何不可共享的资源,因此它永远不会导致优先级反转问题。
Here we can see that the very purpose of the process means that we pretty much never want it to run, if there is any other thread whatsoever that has something to do.
在这里我们可以看到,进程的真正目的意味着我们几乎不希望它运行,如果有任何其他线程有任何事情要做。
(It also gives us a good measure for when something should be at low priority; if it shouldn't be competing with a thread that exists just to put the CPU into a low-power state, then it shouldn't be low priority).
(它还为我们提供了一个很好的衡量何时应该处于低优先级的方法;如果它不应该与仅仅为了将 CPU 置于低功耗状态而存在的线程竞争,那么它就不应该是低优先级) .
回答by Markus
I guess ProcessPriorityClass.Idlemeans "low" in the taskmanager.
我猜ProcessPriorityClass.Idle在任务管理器中的意思是“低”。
See also: ProcessPriorityClass-Enumeration

