Kann ich die prozentuale CPU-Auslastung eines Prozesses manuell begrenzen?


52

Ich möchte die CPU-Zeit für bestimmte Prozesse (z. B. Firefox, Safari usw.) begrenzen.

Ich kann nicht verstehen, warum solche Programme, auch wenn sie nicht verwendet werden (nichts wird geladen, keine Animationen laufen im Hintergrund, ...), so ressourcenhungrig sind. Warum muss ein Browser 50% oder mehr meiner CPU essen? Kann ich es auf 10% begrenzen?


Dies ist keine direkte Antwort auf Ihre Frage, aber Safari und Firefox haben normalerweise keinen CPU-Hunger. Vielleicht möchten Sie untersuchen, was sie tun. Möglicherweise ist eine Erweiterung / ein Plug-in für den übermäßigen Ressourcenverbrauch verantwortlich, und Sie können es möglicherweise deaktivieren (oder entfernen, wenn Sie es nicht mehr verwenden).
Tim Campbell

Antworten:


7

Es ist nicht genau das, was Sie wollten, aber in Bezug auf Google Drive und Chrome hat dies den Trick für mich getan:

Google Drive ("Sichern und Synchronisieren")

  • Priorisierung aufheben:

    for f in $(pgrep 'Backup and Sync'; pgrep 'FinderSyncAPIExtension'); do renice +20 -p $f; done
    
  • auf normal zurücksetzen:

    for f in $(pgrep 'Backup and Sync'; pgrep 'FinderSyncAPIExtension'); do renice 0 -p $f; done
    

Chrom

  • Priorisierung aller aktuellen Prozesse aufheben:

    for f in $(pgrep 'Chrome'); do renice +20 -p $f; done
    
  • Alle aktuellen Prozesse wieder normalisieren:

    for f in $(pgrep 'Chrome'); do renice 0 -p $f; done
    

44

cputhrottleist das Werkzeug, das Sie brauchen. Sie können es mit Homebrew installieren .

Sie können eine Reihe von Prozessen nach Namen überwachen, indem Sie das unten stehende Bash-Skript ausführen. Ich bin nicht ganz sicher, wie ich dies in ein Anmeldeobjekt verwandeln soll, da cputhrottleSuperuser-Berechtigungen erforderlich sind. Führen Sie es als Skript in einem Automator-Workflow aus.

# Get the Process/App names from Activity Monitor and put them here
apps=("AppOne" "AppTwo" "AppThree")
# Set the respective limits here
limits={30 40 50)

while true; do
  for app in ${apps}; do
    for limit in ${limits}; do
      for pid in $(pgrep ${app}); do
        sudo /path/to/cputhrottle ${pid} ${limit}
      done
    done
  done
done

[Bearbeitet]

Ich habe eine andere Version für dieses Skript hinzugefügt (ein bashSkript), die für Leute nützlich sein kann, die die CPU für mehrere Anwendungen einschränken möchten.

Mit diesem neuen Skript können Sie auch eine Liste angeben, die den Anwendungsnamen und das CPU-Limit enthält.

Der Hauptunterschied besteht darin, dass Sie pro Anwendung ein CPU-Limit hinzufügen können, das nur einmal pro Anwendung ausgeführt wird. Ich habe auch die Option zum Beenden aller cputhrottleProzesse hinzugefügt .

Das Skript setzt voraus, dass beide cputhrottleund pidofinstalliert sind, bevor es ausgeführt wird.

#!/bin/bash

if [[ $EUID > 0 ]]; then
  echo "Please run this script as root/sudo"
  exit 1
fi

# Pass --kill as argument to kill all running cputhrottles
if [ $1 = "--kill" ]; then  
  echo "Looking for running cputhrottles..."
  pids=`pidof cputhrottle`
  for pid in ${pids}; do
    echo "> Killing PID ${pid}"
    sudo kill ${pid}
  done
  echo "Done!"
  exit 0
fi

declare -a applications

# Syntax='application;max-cpu'
applications[0]='Chrome;40'
applications[1]='Firefox;50'
applications[2]='pycharm;40'
applications[3]='webstorm;40'
applications[4]='Safari;35'

for i in "${applications[@]}"; do
  app=(${i//;/ })
  app_name=${app[0]}
  cpu_limit=${app[1]}

  printf "\nLooking for ${app_name}...\n"
  pids=`pidof ${app}`
  for pid in ${pids}; do
    echo "> PID=${pid}, CPU=${cpu_limit}"
    sudo cputhrottle ${pid} ${cpu_limit} &
  done
done

printf "\nDone!\n"
echo "Run this script passing '--kill' as argument to remove all cputhrottles."

Quelle:


3
Wie in einem anderen Kommentar erwähnt , wurde cputhrottledas Forumula von Homebrew am 17. Februar 2019 entfernt, da es nicht mehr funktioniert . Yosemite war die letzte unterstützte Version von macOS cputhrottle.
Kasimir

@Casimir und was nun?
Peter Samokhin

@PeterSamokhin Entschuldigung, ich kenne keine Alternative. Aber ich habe auch in letzter Zeit nicht gesucht.
Kasimir,

15

Sie können in der Tat! Es gibt CPUThrottle , mit dem Sie eine zu beschränkende PID angeben können.

Beachten Sie, dass sie aus einem bestimmten Grund versuchen, so viel zu verwenden. Es ist ein nützliches Tool, aber Sie werden feststellen, ob es an einem Tag für Sie besser oder schlechter wird.


1
Interessant. Aber mit diesem Dienstprogramm muss ich ein Programm starten, seine PID (s) finden und cputhrottle manuell verwenden. Jedes Mal, wenn ich es starte. Gibt es etwas, das es mir erlaubt, dem System mitzuteilen: "Führen Sie dieses Programm ab heute immer mit maximal 25% CPU aus"?
Pietro

Soweit ich weiß, bin ich bisher nur auf CPUThrottle gestoßen.
Nicholas Smith


11

Obwohl dies keine direkte Antwort auf die Frage des OP ist, haben Sie ein Problem mit einem bestimmten Prozess, der zu viel CPU-Zeit in Anspruch nimmt und Ihren Computer unbrauchbar macht, und es macht Ihnen nichts aus, wie lange dieser Prozess dauert, um den Vorgang abzuschließen Bei der Aufgabe, an der er arbeitet, können Sie renicedie Priorität dieses Prozesses ändern, damit er sich gut verhält (daher der Name).

Zunächst müssen Sie die PID des Prozesses ermitteln, der die CPU-Ressourcen verbraucht. Sie können dies entweder in Activity Monitor oder in Terminal.app mit dem psBefehl tun. Geben Sie beispielsweise Folgendes ein, um die PID des Safari-Browsers zu ermitteln:

MacBook:~😈  ps -ef | grep Safari
  501 17452   263   0 11:36pm ??         4:15.60 /Applications/Safari.app/Contents/MacOS/Safari

Die zweite Zeile oben ist die Ausgabe, und die PID beträgt in diesem speziellen Fall 17452.

Die nächste Aufgabe besteht darin, die Priorität des Prozesses zu ändern (sagen wir, wir möchten Safari so gestalten, dass es sich gut verhält). Geben Sie dazu in Terminal.app Folgendes ein:

MacBook:~😈  renice -n 10 -p 17452

Die -nOption ändert den Nizza-Level, indem 10 zum aktuellen Wert addiert wird (standardmäßig 0). Der Wertebereich liegt zwischen -20 und 20, wobei der niedrigste Wert die höchste Priorität bedeutet. Als normaler Benutzer können Sie die Werte 0 bis 20 verwenden. Um einen negativen Wert zuzuweisen, müssen Sie über Root-Berechtigungen verfügen (z sudo. B. Befehl verwenden). Lesen Sie mehr über niceund reniceindem Sie man niceund man renicein Terminal.app eingeben .

niceund beschränken reniceSie nicht den Prozentsatz der für eine bestimmte Anwendung per se verfügbaren CPU, sondern erlauben es, die Planungspriorität oder mit anderen Worten, wie viel CPU-Zeit ein Prozess erhalten wird, zu ändern. Dies hängt alles von der CPU-Auslastung Ihres Systems ab. Wenn das System also nicht ausgelastet ist, werden Sie höchstwahrscheinlich keinen Unterschied feststellen.


Gibt es eine Möglichkeit, die aktuelle Priorität eines Prozesses anzuzeigen?
theonlygusti

Verwenden Sie top oder htop, um den aktuellen Wert eines Prozesses anzuzeigen. (brew install htop), (sudo apt install htop). Sie sehen eine der Spalten mit dem Wert.
Tmanok

6

Dafür gibt es einen einfachen Einzeiler:

ps axu | grep Chromium | grep -v grep | awk '{print $2}' | sudo xargs -n 1 -I'{}' sh -c 'cputhrottle {} 10 &'

Geben Sie Ihren App-Namen anstelle von Chrom und den gewünschten Prozentsatz anstelle von 10 ein und los geht's!


Dies funktionierte gut, obwohl es reduziert werden kann: pgrep Dropbox | sudo xargs -n 1 -I'{}' sh -c 'cputhrottle {} 10 &'. Ich bin mir jedoch nicht sicher, ob macOS bereits pgrepinstalliert ist.
Bigsweater

5

Dies basiert auf einer vorherigen Antwort, aber das Hinzufügen des Traps für Strg + C, um sicherzustellen, dass der gedrosselte Prozess im Status "Continue" verbleibt, und das Hinzufügen, set -edamit dieses Skript ordnungsgemäß beendet wird, wenn der Prozess selbst beendet wird:

trap ctrl_c_fn INT

function ctrl_c_fn() {
    echo "caught CTRL-C, exiting"
    kill -SIGCONT $pid
    exit
}

echo "enter process id"
read pid
echo "press Ctrl-C to exit"

set -e

while true; do
    kill -SIGSTOP $pid
    sleep 0.009
    kill -SIGCONT $pid
    sleep 0.001
done

3

Der Link, den Nicholas Smith gepostet hat, funktioniert nicht mehr. Also habe ich eine andere App gefunden, die den Trick für die Leute macht, die sie erneut suchen. Die App ruft Apppolice auf.

http://www.macupdate.com/app/mac/49836/apppolice


2
Ähnlich wie bei AppPolice gibt es AppTamer ( stclairsw.com/AppTamer ). Ein Wort zur Vorsicht: Als ich diesen Kommentar schrieb, war AppTamer noch nicht mit OSX Sierra kompatibel.
John Mark Mitchell

Oh mein Gott, was für ein Fund. Einfach AppTamer installiert. Freut mich zu berichten, funktioniert fantastisch gut. Ich verwende es, um das neue StarCraft-Remastering in der Linie zu halten, wenn ich die Alt-Tab-Taste drücke. Oh und ich habe vergessen zu erwähnen, dass ich mit macOS Sierra 10.12.6 arbeite. Danke für den Vorschlag!
Cavalcade

Apppolice wurde eingestellt.
LаngLаngС

Funktioniert aber trotzdem ganz gut.
Phil Pirozhkov

3

Dies ist mein letztes Skript. Halten Sie den Befehl cputhrottle sauber. Führen Sie nur dann ein neues Skript aus, wenn es nicht existiert

#!/bin/bash

###
# setup cputhrottle if doesn't exists
###
set_service_cpu_limit(){
    service_pid=$(pgrep $1)
    limit=$2
    if [[ ! -z $service_pid  ]]; then
        service_cpu=$(ps aux | grep "sudo cputhrottle $service_pid $limit" | grep -v grep | wc -l)
        if [[ ! $service_cpu -gt 0 ]]; then
            sudo cputhrottle $service_pid $limit &
        fi
    fi
}

###
# main loop
###
while true; do
    set_service_cpu_limit bzfilelist 2
    set_service_cpu_limit bztransmit 2
    sleep 0.5
done

3

Das Skript, das Dimitri geschrieben hat, funktioniert gut (unter MacOS), läuft aber nach dem Schließen der Anwendung mit Fehlern weiter. Ich habe es geändert, um es fertig zu stellen (mit einer Fehlermeldung über die nicht gefundene PID):

echo "enter process id"
read pid
echo "press Ctrl-C to exit"

while kill -SIGSTOP $pid; do
    sleep 0.009
    kill -SIGCONT $pid
    sleep 0.001
done

Dies sollte wahrscheinlich eine Bearbeitung von Dimitris ursprünglicher Antwort sein, um diese Antwort zu verbessern, und nicht eine separate Antwort mit (im Grunde) den gleichen Informationen.
4.

2

Das hat bei mir funktioniert

echo "enter process id"
read pid
echo "press Ctrl-C to exit"

while true; do
    kill -SIGSTOP $pid
    sleep 0.009
    kill -SIGCONT $pid
    sleep 0.001
done
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.