В Windows PowerShell, как можете да зададете максималния CPU % за използване от скрипта?

Търся да огранича процента на процесорното време, използвано от процес на PowerShell, до определен брой -- в името на аргумента, нека си представим, че е 13%.

Други опции, които не са точно това, което ми трябва: 1) Задаване на приоритет. 2) Задаване на афинитет на процесора.

По принцип имаме софтуер за наблюдение, който се оплаква, ако общото използване на процесора стане твърде високо. Имаме ежедневен процес, който задейства това -- предимно безобидно, но твърде много фалшиви положителни резултати в системата за наблюдение и хората стават привикнали към предупреждения/грешки, когато не желаем това.

Самият процес също много възбужда lsass.exe, докато работи, а също така се случват и други процеси.

Не познавам PowerShell и се опитвам да поправя Powershell на някой друг. Очевидно едно основно пренаписване би било хубаво в някакъв бъдещ момент, но засега камбаните бият и дразнят хората.


person Community    schedule 06.08.2009    source източник
comment
Не би ли било истинско решение да го стартирате с по-нисък приоритет и да кажете на монитора за използване на процесора да игнорира процесите с нисък приоритет?   -  person Joachim Sauer    schedule 06.08.2009
comment
Останах с впечатлението, че това е ръчно нещо, което бихте направили чрез диспечера на задачите. Ако този скрипт на powershell се задейства като част от работа, не е реалистично някой да седи там и да наблюдава диспечера на задачите и да задава афинитета, докато работи.   -  person Michael Beck    schedule 10.01.2018


Отговори (6)


Това, което искаш, всъщност не е възможно. Ядрото на Windows отговаря за планирането на процесора - и с право. (Аз например не искам да се връщам към DOS в реален режим).

Най-доброто, което можете да направите, е да вмъкнете дълъг Sleep() между всеки ред на скрипта. Но няма гаранция, че който и да е конкретен Powershell cmdlet / функция / и т.н. ще се дроселира по начина, по който искате. Извикванията на Windows API, които в крайна сметка изпълняват мръсната работа на всеки оператор, със сигурност няма да го направят.

По ирония на съдбата Реймънд засегна тази тема само преди няколко дни: http://blogs.msdn.com/oldnewthing/archive/2009/07/27/9849503.aspx

Моето истинско предложение е да промените скрипта си, така че да изглежда така:

try {
    Stop-CpuMonitor

    # ...the current script contents...
}
finally {
    Start-CpuMonitor
}                
person Richard Berg    schedule 06.08.2009

От моя опит няма начин да се определи какъв процент от CPU Powershell ще може да използва. Мисля, че най-добрият начин на действие би бил да зададете приоритета на Powershell на Нисък, за да позволите на други задачи/програми да вървят първи. Мисля, че първата публикация има прилично предложение за използване на паузите (бих гласувал за, но съм под 15 точки репутация, за да го направя) и това е нещо, което може да разгледате, но не мисля, че ще ви даде контролът, който търсите. Съжалявам, отговорът ми е по-скоро предложение, отколкото решение.

/мат

person Matt Dewey    schedule 06.08.2009

Искрено се съмнявам, че има особено прост начин да постигнете това, което питате. Ако загрижеността за процесора е голяма работа, бих комбинирал няколко тактики и бих оставил планировчика да се погрижи за останалото - той всъщност е доста добър в управлението на натоварването.

Предложението за използване на ThreadPriority е малко проблематично, тъй като PowerShell създава всяка нова команда в нова нишка, която можете да заобиколите, като капсулирате всичко на един ред, cmdlet или функция от някакъв вид. По-добре да изпратите целия процес на powershell на празен ход:

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

Забележка: това ще изпрати ВСИЧКИ екземпляри на powershell в неактивен режим, което може да не е желаният ефект. И със сигурност не пречи на скрипта да повиши собствения си приоритет.

Също така, както е споменато тук - затрупването на вашия код с команди за заспиване може да бъде ефективен начин да се гарантира, че другите процеси имат достатъчно процесорно време за обработка на техния код. Дори 50-100ms са почти цяла вечност за един процесор.

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

Между тези две тактики вашият скрипт ще се изпълнява, когато е наличен, и любезно ще се покланя на други изисквания на процесора, когато възникнат.

person Goyuix    schedule 12.08.2009

Въпреки че не знам за начин действително да огранича използването на който и да е процес до определено количество потребление на процесора в проценти, реших, че може би човек може да промени приоритета на нишката на PowerShell. Затова написах бърз скрипт и проведох тест.

Резултатът беше, че както при „Нормално“, така и при „Най-ниско“, необходимото време беше приблизително еднакво. Гледайки приспособлението за измерване на процесора, взетото използване на процесора беше приблизително 27%, но работех на четириядрен модул, така че това не е изненадващо. И в двата случая отнемаше целия процесор. Машината ми не правеше нищо друго по това време, така че това бяха другите 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 се посочва:

Операционните системи не са задължени да зачитат приоритета на нишка.

person Lee    schedule 06.08.2009

Една възможност може да е използването на process lasso. Имам само положителни резултати при автоматично дроселиране на процеси, които не са изключени от мен, когато използването на процесора надвиши определен процент.

Имайте предвид, че има доста ограничена безплатна версия, която можете да използвате, за да тествате, ако работи за вас.

PS: Не работя за никого. Просто предлагам програма, която е работила за мен в миналото.

person Christopher Hauck    schedule 23.04.2016

Използвайте AddType на C# скриптов литерал, който отново използва P/Invoke за извикване на функциите на Win32 CreateJobObject, SetInformationJobObject (предаване на JOBOBJECT_CPU_RATE_CONTROL_INFORMATION) и AssignProcessToJobObject. Вероятно ще бъде по-лесно да напишете обвиваща програма на C, която задава ограниченията и създава скрипта на PowerShell в такава работа.

person RolKau    schedule 03.02.2021