4

我希望将 PowerShell 进程使用的 CPU 时间百分比限制为某个数字——为了论证,我们假设它为 13%。

其他不正是我需要的选项:1)设置优先级。2) 设置 CPU 亲和性。

基本上,如果总 CPU 使用率过高,我们有监控软件会抱怨。我们有一个日常流程来解决这个问题——大多数情况下是无害的,但是监控系统中有太多误报,当我们不希望出现警告/错误时,人们会习惯于出现警告/错误。

进程本身也会让 lsass.exe 非常兴奋,因为它运行时,其他进程也会发生。

我不知道 PowerShell,正在尝试修复 Somebody Else 的 Powershell。显然,在未来的某个时候,从头开始重写会很好,但就目前而言,钟声正在响起,让人们烦恼。

4

6 回答 6

3

你所要求的实际上是不可能的。Windows 内核负责调度 CPU ——这是理所当然的。(我不想回到实模式DOS)。

您可以做的最好的事情是在脚本的每一行之间插入一个长的 Sleep() 。但是不能保证任何特定的 Powershell cmdlet / 函数 / 等都会按照你想要的方式自我节流。最终执行每个语句的脏工作的 Windows API 调用肯定不会。

具有讽刺意味的是,Raymond 几天前就谈到了这个话题:http: //blogs.msdn.com/oldnewthing/archive/2009/07/27/9849503.aspx

我真正的建议是修改您的脚本,使其看起来像:

try {
    Stop-CpuMonitor

    # ...the current script contents...
}
finally {
    Start-CpuMonitor
}                
于 2009-08-06T14:45:25.527 回答
1

根据我的经验,没有办法规定 CPU Powershell 可以使用的百分比。我认为最好的做法是将 Powershell 的优先级设置为低,以允许其他任务/程序先行。我认为第一篇文章有​​一个不错的使用暂停的建议(我会赞成,但我的声望点数低于 15 分),这是你可能会考虑的,但我认为它不会给你您正在寻找的控件。对不起,我的回答更像是一个建议而不是一个解决方案。

/马特

于 2009-08-06T16:28:21.937 回答
1

我真诚地怀疑是否有一种特别简单的方法可以完成您的要求。如果 CPU 问题很重要,我会结合几种策略,让调度程序来处理其余的事情——它实际上非常擅长管理负载。

使用 ThreadPriority 的建议有点问题,因为 PowerShell 在新线程中生成每个新命令,您可以通过将所有内容封装在一行、一个 cmdlet 或某种函数上来解决这个问题。最好将整个 powershell 进程发送到空闲:

Get-Process -name powershell | foreach { $_.PriorityClass = "Idle" }

注意:这会将所有 powershell 实例发送到空闲状态,这可能不是预期的效果。当然也不会阻止脚本提高自己的优先级。

此外,正如这里提到的 - 使用睡眠命令乱扔代码可能是确保其他进程有足够的 CPU 时间来处理其代码的有效方法。即使是 50-100 毫秒,对于处理器来说也几乎是永恒的。

[System.Threading.Thread]::Sleep(50)

在这两种策略之间,您的脚本将在可用时运行,并在出现其他 CPU 需求时优雅地低头。

于 2009-08-12T14:26:05.403 回答
0

虽然我不知道实际上无法将任何进程的使用限制为特定数量的 CPU 消耗百分比,但我认为也许可以改变 PowerShell 线程的优先级。所以我写了一个快速脚本并进行了测试。

结果是,在“正常”和“最低”中,所用时间大致相同。查看 CPU Meter 小部件,CPU 使用率约为 27%,但我在四核机器上运行,所以这并不奇怪。在这两种情况下,它都占用了一个 CPU。我的机器当时没有做太多其他事情,所以我猜那是另外 2%。

也许在更繁忙的机器上结果会有所不同。

这是脚本:

function Spin
{
    param($iterations)

    for($i = 0; $i -lt $iterations; ++$i)
    {
        # Do nothing
    }
}

$thread = [System.Threading.Thread]::CurrentThread

Write-Host $thread.Priority
$start = [DateTime]::Now
Write-Host "[$start] Start"

Spin 10000000

$end = [DateTime]::Now
Write-Host "[$end] End"
$span = $end - $start
Write-Host "Time: $span"

$thread.Priority = "Lowest"
Write-Host $thread.Priority
$start = [DateTime]::Now
Write-Host "[$start] Start"

Spin 10000000

$end = [DateTime]::Now
Write-Host "[$end] End"
$span = $end - $start
Write-Host "Time: $span"

$thread.Priority = "Normal"

结果如下:

Normal
[08/06/2009 08:12:38] Start
[08/06/2009 08:12:55] End
Time: 00:00:16.7760000
Lowest
[08/06/2009 08:12:55] Start
[08/06/2009 08:13:11] End
Time: 00:00:16.8570000

另请注意,在它的文档中Thread.Priority指出:

操作系统不需要遵守线程的优先级。

于 2009-08-06T15:23:49.647 回答
0

可能正在使用process lasso. 当 CPU 使用率超过一定百分比时,我对自动限制不被我排除的进程只有积极的结果。

请记住,有一个相当有限的免费版本可用于测试,如果它适合您的话。

PS:我不为任何人工作。我只是提供一个过去对我有用的程序。

于 2016-04-23T20:29:10.057 回答
0

在 C# 脚本文字上使用 AddType,它再次使用 P/Invoke 调用 Win32 函数 CreateJobObject、SetInformationJobObject(传递 JOBOBJECT_CPU_RATE_CONTROL_INFORMATION)和 AssignProcessToJobObject。用 C 语言编写一个设置限制并在此类作业中生成 PowerShell 脚本的包装程序可能会更容易。

于 2021-02-03T21:02:45.280 回答