C# 以编程方式限制在服务内运行的线程的 CPU 使用率

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/482592/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 05:09:10  来源:igfitidea点击:

Programmatically limit CPU Usage of a Thread running inside a Service

c#multithreadingwindows-servicesservice

提问by user57175

I'm using VB9 (VS2008).

我正在使用 VB9 (VS2008)。

I've created a Windows Service that indexes some folders regularly.

我创建了一个 Windows 服务,它定期为一些文件夹编制索引。

Is there a way I can put an upper limit on the CPU usage depending upon the current system state, i.e., if the system is idle, the thread can use the CPU as much as it needs, but if there are other programs/processes running then it should use the CPU in way that does not make the system slow.

有没有办法可以根据当前系统状态设置 CPU 使用率上限,即,如果系统空闲,线程可以根据需要使用 CPU,但如果有其他程序/进程正在运行那么它应该以不会使系统变慢的方式使用 CPU。

采纳答案by ShuggyCoUk

You can reduce the priority of the thread, in .Net via Thread.Priority

您可以通过Thread.Priority在 .Net 中降低线程的优先级

Setting it to BelowNormal will mean that other threads will be scheduled in front of it.

将其设置为 BeyondNormal 将意味着其他线程将被安排在它前面。

This can lead to the thread being starved, but it sounds like this is an acceptable design decision for your needs.

这可能会导致线程饿死,但听起来这是一个可以满足您需求的设计决策。

Note that since you are performing considerable disk IO this actually will be the main impact of the back ground task, and you may find that reducing the priority is not sufficient (since the disk IO will continue in parts even while the thread is throttled.

请注意,由于您正在执行大量磁盘 IO,这实际上将是后台任务的主要影响,您可能会发现降低优先级是不够的(因为即使线程受到限制,磁盘 IO 也会部分继续。

A monitoring thread that checks the usage of the machine (optionally caring only when at least one interactive user is present) could pause the indexing (or throttle the IO considerably). This will be more important on modern machines where there are many available cores (and hyper threading virtual cores) which mean that despite the user actually doing a lot of work spare resources exist to execute your indexing thread but not really to execute the disk IO.

检查机器使用情况的监控线程(可选地仅在至少有一个交互式用户存在时才关心)可以暂停索引(或显着限制 IO)。这在有许多可用内核(和超线程虚拟内核)的现代机器上更为重要,这意味着尽管用户实际上做了很多工作,但仍然存在空闲资源来执行您的索引线程,而不是真正执行磁盘 IO。

You may also want to consider whether you check the Power Schemeto determine if you should run at that time (since the battery drain from both heavy disk access is not inconsiderable)

您可能还需要考虑是否检查电源方案以确定您是否应该在那个时候运行(因为两个重磁盘访问造成的电池消耗不是微不足道的)

If you wish to do even more to reduce the impact of this background IO bound task versions of windows from Vista onwards add two useful APIs:

如果您希望做更多事情来减少 Vista 以后的 Windows 后台 IO 绑定任务版本的影响,请添加两个有用的 API:

Low Priority I/O

低优先级 I/O

This allows your code to schedule I/O at a lower priority than other I/O.

这允许您的代码以比其他 I/O 更低的优先级调度 I/O。

Windows Task Scheduler

Windows 任务计划程序

You can use this to schedule things to run at "system idle time". This when the system isn't busy, and the user is not present.

您可以使用它来安排事情在“系统空闲时间”运行。这是当系统不忙且用户不在时。

回答by 1800 INFORMATION

If you use the SetThreadPriorityAPI, you can configure the thread to use a lower thread priority than normal. The thread will use all available CPU resources when the system is idle, but will relinquish CPU time to any threads that have a higher priority.

如果您使用SetThreadPriorityAPI,您可以将线程配置为使用比正常更低的线程优先级。当系统空闲时,线程将使用所有可用的 CPU 资源,但会将 CPU 时间放弃给任何具有更高优先级的线程。

回答by macbirdie

Much of the burden on your system coming from your indexing process is probably the disk I/O, so besides what ShuggyCoUk said, if your process works in Vista/Windows Server 2008, you can also change disk I/O priority to background. That's how most paging, defrag and other maintenance tasks work on those systems. If not, you can also monitor the disk i/o queue to see if there are pending operations coming from user interaction.

来自索引进程的大部分系统负担可能是磁盘 I/O,所以除了 ShuggyCoUk 所说的之外,如果您的进程在 Vista/Windows Server 2008 中工作,您还可以将磁盘 I/O 优先级更改为后台。这就是大多数分页、碎片整理和其他维护任务在这些系统上的工作方式。如果没有,您还可以监视磁盘 i/o 队列以查看是否有来自用户交互的挂起操作。

回答by Foredecker

On XP, ShuggyCoUk is correct. The first thing to do is simply lower the thread priority to something below 8. This will mean that any other thread or process that is running with priority 8 or greater will always run instead of your thread. Note, I do not recommend simply setting your process priority to <8, just the thread (or threads) you want to run 'nicely'.

在 XP 上,ShuggyCoUk 是正确的。要做的第一件事就是将线程优先级降低到 8 以下。这意味着任何其他以 8 或更高优先级运行的线程或进程将始终运行,而不是您的线程。请注意,我不建议简单地将您的进程优先级设置为 <8,而只是将您想要“良好”运行的线程(或多个线程)设置为。

As Shuggy has pointed out, the issue isn't he CPU time - it is the I/O your service is generating. On XP, all I/O's are treated the same - so your I/O has the potential to interfere with other things.

正如 Shuggy 所指出的,问题不在于 CPU 时间——而是您的服务生成的 I/O。在 XP 上,所有 I/O 的处理方式都是一样的 - 因此您的 I/O 可能会干扰其他事物。

Vista (and soon on Win7) has two things designed to do exactly what you want.

Vista(很快会在 Win7 上)有两件事情可以做你想做的事。

The first is the Windows Task Scheduler. You can use this to schedule things to run at "system idle time". This when the system isn't busy, and the user is not present.

第一个是Windows 任务计划程序。您可以使用它来安排事情在“系统空闲时间”运行。这是当系统不忙且用户不在时。

The second is Low Priority I/O. This allows your code to schedule I/O at a lower priority than other I/O.

第二个是低优先级 I/O。这允许您的代码以比其他 I/O 更低的优先级调度 I/O。

Both of these together can be used to develop code that is a good system citizen.

这两者一起可用于开发作为良好系统公民的代码。

Note, you should also take mobile systems into account by scaling back or disabling your background item when the system is running on batteries. You can be simple about this - simple turning off on battery power; or sophisticated, taking the Power Schemeinto account, and using that as hint from the user.

请注意,当系统使用电池运行时,您还应该通过缩减或禁用后台项目来考虑移动系统。你可以很简单 - 简单地关闭电池电源;或复杂,考虑到电源方案,并将其用作用户的提示。

Since you are working on writing a service that is a good system citizen, you can do a few other things as well.

由于您正在编写一个良好的系统公民服务,因此您还可以做一些其他的事情。

1) You could monitor the amount of work done over time and slow down or stop if enough progress has been made. 2) Do pay attention to your memory footprint - the smaller the better. This often goes without saying, but it is particular important for services as they run 24/7.

1) 您可以监控随着时间的推移完成的工作量,如果取得了足够的进展,可以放慢速度或停止。2)一定要注意你的内存占用——越小越好。这通常是不言而喻的,但对于 24/7 全天候运行的服务来说尤其重要。