Puis-je limiter manuellement le% de CPU utilisé par un processus?

52

J'aimerais limiter la quantité de temps CPU dédiée à certains processus (par exemple, Firefox, Safari, ...).

Je ne comprends pas pourquoi de tels programmes, même non utilisés (aucun chargement, aucune animation, ne s’exécutant en arrière-plan, ...), sont donc gourmands en ressources. Pourquoi un navigateur doit consommer 50% ou plus de mon processeur? Puis-je limiter à 10%?

Pietro
la source
Ce n'est pas directement une réponse à votre question, mais Safari et Firefox ne consomment normalement pas beaucoup de ressources processeur. Vous voudrez peut-être examiner ce qu'ils peuvent faire. Une extension / un plug-in est peut-être responsable de la consommation excessive de ressources et vous pourrez peut-être le désactiver (ou le supprimer si vous ne l'utilisez plus.)
Tim Campbell

Réponses:

7

Ce n’est pas exactement ce que vous vouliez, mais en ce qui concerne Google Drive et Chrome, c’est ce qui a fait le tour pour moi:

Google Drive ("Sauvegarde et synchronisation")

  • dé-hiérarchiser:

    for f in $(pgrep 'Backup and Sync'; pgrep 'FinderSyncAPIExtension'); do renice +20 -p $f; done
    
  • revenir à la normale:

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

Chrome

  • dé-hiérarchiser tous les processus en cours:

    for f in $(pgrep 'Chrome'); do renice +20 -p $f; done
    
  • remettre à la normale tous les processus en cours:

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

cputhrottleest l'outil dont vous avez besoin. Vous pouvez l'installer avec Homebrew .

Vous pouvez surveiller une série de processus par leur nom en exécutant le script Bash ci-dessous. Je ne sais pas trop comment transformer cela en un élément de connexion, car il cputhrottlenécessite des autorisations de superutilisateur. Exécutez-le en tant que script, dans un flux de travail Automator, peu importe:

# 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

[Édité]

J'ai ajouté une version différente pour ce script (un bashscript), ce qui pourrait être utile aux personnes cherchant à limiter le processeur pour plusieurs applications.

Ce nouveau script vous permet également de spécifier une liste contenant le nom de l'application et la limite de CPU pour celle-ci.

La principale différence est que vous pouvez ajouter une limite de cpu par application et qu'elle ne s'exécutera qu'une fois par application. J'ai également ajouté l'option permettant de supprimer tous les cputhrottleprocessus.

Le script suppose que les deux cputhrottleet pidofsont installés avant de l'exécuter.

#!/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."

La source:

fny
la source
3
Comme souligné dans un autre commentaire , cputhrottlela forumula a été retirée d'Homebrew le 17 février 2019 car elle ne fonctionne plus . Yosemite était la dernière version de macOS à prendre en charge cputhrottle.
Casimir
@ Casimir et maintenant, que faire?
Peter Samokhin le
@PeterSamokhin Désolé, je ne connais pas d'alternative. Mais je n'ai pas non plus cherché récemment.
Casimir le
15

Vous pouvez en effet! Il y a CPUThrottle , qui permet de spécifier un PID à restreindre.

Notez, ils essaient d'utiliser cela beaucoup pour une raison, c'est un outil utile, mais que ça le rende meilleur ou pire pour vous au jour le jour, vous le découvrirez.

Nicholas Smith
la source
1
Intéressant. Mais avec cet utilitaire, je dois lancer un programme, trouver son ou ses PID et utiliser manuellement cputhrottle. A chaque fois que je le lance. Y at-il quelque chose qui me permet de dire au système: «À partir d’aujourd’hui, exécutez toujours ce programme avec un maximum de 25% de CPU»?
Pietro
Autant que je sache, je n'ai jamais vu que CPUThrottle.
Nicholas Smith
404 Fichier non trouvé
André Levy le
11

Bien que ce ne soit pas une réponse directe à la question du PO, si vous rencontrez un problème avec un processus particulier prenant trop de temps de votre temps processeur et rendant votre ordinateur inutilisable, vous n'avez pas à vous soucier du temps que ce processus prend pour terminer le processus. tâche sur laquelle vous travaillez, vous pouvez utiliser la renicetouche pour modifier la priorité de ce processus, pour qu’il se comporte bien (d’où son nom).

Tout d'abord, vous devez trouver le PID du processus qui utilise les ressources du processeur. Vous pouvez le faire dans Activity Monitor ou dans Terminal.app à l'aide de la pscommande. Par exemple, pour trouver le PID du navigateur Safari, tapez:

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

La deuxième ligne ci-dessus est la sortie et le PID est 17452 dans ce cas particulier.

Ensuite, la tâche suivante consiste à modifier la priorité du processus (disons que nous voulons que Safari se comporte bien). Pour ce faire, dans Terminal.app, tapez:

MacBook:~😈  renice -n 10 -p 17452

L' -noption modifie le niveau de précision en ajoutant 10 à la valeur actuelle (0 par défaut). La plage de valeurs est comprise entre -20 et 20, la valeur minimale désignant la priorité la plus élevée. En tant qu'utilisateur ordinaire, vous pouvez utiliser les valeurs 0 à 20. Pour affecter une valeur négative, vous devez disposer des privilèges root (par exemple, utilisez la sudocommande). En savoir plus sur niceet reniceen tapant man niceet man renicedans Terminal.app.

niceet renicene limitent pas le pourcentage de la CPU disponible pour une application donnée en soi, ils permettent toutefois de changer la priorité de planification, ou en d'autres termes, la quantité de temps CPU qu'un processus obtiendra. Tout cela est relatif à la charge du processeur de votre système. Par conséquent, si le système est sous-utilisé, vous ne verrez probablement aucune différence.

Mike
la source
Y a-t-il un moyen de voir la priorité actuelle d'un processus?
theonlygusti
utilisez top ou htop pour afficher la valeur actuelle d'un processus. (brassez installer htop), (sudo apt install htop). Vous verrez l'une des colonnes contenant la valeur.
Tmanok
6

Il y a une simple ligne pour faire tout cela:

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

Ecrivez le nom de votre application au lieu de chrome et le pourcentage souhaité au lieu de 10 et vous voilà prêt à partir!

Yuriy Nasretdinov
la source
Cela a bien fonctionné, mais il peut être réduit à: pgrep Dropbox | sudo xargs -n 1 -I'{}' sh -c 'cputhrottle {} 10 &'. Je ne suis pas sûr si macOS est pgrepinstallé avec , cependant.
BigSweater
5

Ceci est basé sur une réponse précédente, mais l'ajout de l'interruption pour ctrl + c pour s'assurer que le processus en cours de limitation est laissé dans un état de continuation, et l'ajout de set -esorte que ce script se ferme proprement si le processus se ferme:

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
utilisateur100375
la source
3

Le lien que Nicholas Smith a posté ne fonctionne plus. J'ai donc trouvé une autre application qui fait l'affaire pour les personnes qui la recherchent à nouveau. l'application appelle Apppolice.

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

John Wells
la source
2
Semblable à AppPolice, il existe AppTamer ( stclairsw.com/AppTamer ). Un mot de prudence: au moment de la rédaction de ce commentaire, AppTamer n’était pas encore compatible avec OSX Sierra.
John Mark Mitchell
Oh mon Dieu, quelle trouvaille. Je viens d'installer AppTamer. Heureux de signaler fonctionne à merveille. Je l'utilise pour garder le nouveau StarCraft remasterisé en ligne lorsque je modifie l'onglet. Oh, et j'ai oublié de mentionner, je suis sous macOS Sierra 10.12.6. Merci pour la suggestion!
cavalcade
Apppolice a été discontinué.
LаngLаngС
Mais fonctionne toujours très bien.
phil pirozhkov
3

Ceci est mon dernier script, maintenez la commande cputhrottle propre et n’en exécutez une nouvelle si elle n’existe pas

#!/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
Alejo JM
la source
3

Le script écrit par Dimitri fonctionne bien (sous macOS), mais il continue à fonctionner avec des erreurs après la fermeture de l'application. Je l'ai changé pour le terminer (avec un message d'erreur sur le PID introuvable):

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
Bart Meerdink
la source
Cela devrait probablement être une modification apportée à la réponse originale de Dimitri, afin d'améliorer cette réponse, et non une réponse séparée avec (essentiellement) les mêmes informations.
FSB
2

ce sh a fonctionné pour moi

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
Dmitriy Buldakov
la source