32 votes

Limiter certains processus au % de CPU - Linux

J'ai le problème suivant : certains processus, générés dynamiquement, ont tendance à consommer 100% du CPU. Je voudrais limiter tous les processus correspondant à un certain critère (par exemple le nom du processus) à un certain pourcentage du CPU.

Le problème spécifique que j'essaie de résoudre est l'exploitation des processus de travail de folding@home. La meilleure solution à laquelle j'ai pensé est un script perl qui est exécuté périodiquement et qui utilise l'utilitaire cpulimit pour limiter les processus (si vous êtes intéressé par plus de détails, regardez ceci article de blog ). Cela fonctionne, mais c'est un hack :/

Des idées ? Je voudrais laisser la gestion des processus à l'OS :)


Merci encore pour les suggestions, mais nous sommes toujours à côté de la plaque :)

La solution "slowDown" est essentiellement ce que fait l'utilitaire "cpulimit". Je dois encore faire attention aux processus à ralentir, tuer le processus "slowDown" une fois que le processus travailleur est terminé et en démarrer de nouveaux pour les nouveaux processus travailleurs. C'est précisément ce que j'ai fait avec le script Perl et une tâche cron.

Le principal problème est que je ne sais pas à l'avance quels processus limiter. Ils sont générés dynamiquement.

Peut-être existe-t-il un moyen de limiter tous les processus d'un utilisateur à un certain pourcentage de CPU ? J'ai déjà configuré un utilisateur pour exécuter les travaux de folding@home, en espérant pouvoir le limiter avec le fichier /etc/security/limits.conf. Mais le plus proche que j'ai pu obtenir ici est le temps total de CPU par utilisateur...

Ce serait cool si on avait quelque chose qui nous permette de dire : "La somme de tous les % d'utilisation du CPU des processus de cet utilisateur ne peut pas dépasser 50%". Et ensuite laisser les processus se battre pour ces 50% de CPU en fonction de leurs priorités...


Les gars, merci pour vos suggestions, mais il ne s'agit pas de priorités - je veux limiter le % de CPU même quand il y a beaucoup de temps CPU disponible. Les processus sont déjà à faible priorité, donc ils ne causent pas de problèmes de performance.

Je voudrais juste empêcher le CPU de tourner à 100% pendant de longues périodes...

1 votes

Pourquoi est-ce une mauvaise chose ? S'ils sont correctement réglés, ils ne devraient pas interférer avec d'autres processus. Ils vont juste (en fait) récupérer tous les cycles restants...

3 votes

En lisant l'article du blog, on a l'impression qu'il veut que les processeurs aient un certain temps d'inactivité pour qu'ils ne soient pas trop chauds. C'est pour cela que j'ai arrêté de faire SETI@Home - mes processeurs ne duraient pas très longtemps parce qu'ils chauffaient tout le temps.

0 votes

Oui, je n'ai jamais eu de panne de CPU due à une surchauffe, même en utilisant SETI@Home. Et je n'ai jamais utilisé quelque chose de plus sophistiqué que les unités HSF fournies avec mes processeurs.

22voto

Datageek Points 2846

J'ai eu un problème légèrement similaire. Je ne voulais pas exécuter un démon cpulimit mais je voulais limiter le processus dès le début lors de son exécution. Finalement, j'ai utilisé la commande suivante qui fait très bien l'affaire.

En supposant que nous voulons diminuer le CPU d'un processus gzip :

    gzip backup.tar & sleep 2 & cpulimit --limit 10 -e gzip -z

Options :

  • J'ai trouvé Sleep utile car cpulimit ne détectait pas toujours le nouveau processus.
  • --limit 10 limite le CPU à 10%.
  • -z ferme la limite cpu quand le processus gzip se termine

13voto

blabla999 Points 2316

Je ne me souviens pas et je ne pense pas qu'il y avait quelque chose comme ça dans le scheduler unix. Vous avez besoin d'un petit programme qui contrôle l'autre processus et qui fait ce qui suit :

loop
    wait for some time tR
    send SIGSTOP to the process you want to be scheduled
    wait for some time tP
    send SIGCONT to the process.
loopEnd

le rapport tR/tP contrôle la charge du processeur.


Voici une petite preuve de concept. "busy" est le programme qui utilise votre temps cpu et que vous voulez faire ralentir par "slowDown" :

> cat > busy.c:
    main() { while (1) {}; }

> cc -o busy busy.c
> busy &
> top

Tasks: 192 total,   3 running, 189 sleeping,   0 stopped,   0 zombie
Cpu(s): 76.9% us,  6.6% sy,  0.0% ni, 11.9% id,  4.5% wa,  0.0% hi,  0.0% si
Mem:   6139696k total,  6114488k used,    25208k free,   115760k buffers
Swap:  9765368k total,  1606096k used,  8159272k free,  2620712k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
26539 cg        25   0  2416  292  220 R 90.0  0.0   3:25.79 busy
...

> cat > slowDown
while true; do
 kill -s SIGSTOP $1
 sleep 0.1
 kill -s SIGCONT $1
 sleep 0.1
done

> chmod +x slowDown
> slowDown 26539 &
> top
Tasks: 200 total,   4 running, 192 sleeping,   4 stopped,   0 zombie
Cpu(s): 48.5% us, 19.4% sy,  0.0% ni, 20.2% id,  9.8% wa,  0.2% hi,  2.0% si
Mem:   6139696k total,  6115376k used,    24320k free,    96676k buffers
Swap:  9765368k total,  1606096k used,  8159272k free,  2639796k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
26539 cg        16   0  2416  292  220 T 49.7  0.0   6:00.98 busy
...

ok, ce script a besoin d'un peu plus de travail (par exemple, pour se préoccuper d'être INTR-upted et laisser le processus contrôlé continuer au cas où il a été arrêté à ce moment), mais vous avez compris le point. J'écrirais aussi ce petit script en C ou similaire et je calculerai le ratio cpu à partir d'un argument de ligne de commande.....

concerne

0 votes

Le site cpulimit fonctionne de cette manière. Elle surveille les processus que vous avez définis. Si un processus utilise plus que la limite, elle suspend le processus. -- Vous pouvez consulter le code source dans Github .

8voto

elGEoRgE TheKiLLa Points 470

Je pense que sous Linux, il n'y a pas de solution pour plafonner l'utilisation du processeur, mais il existe un moyen acceptable de limiter tout processus à une certaine utilisation du processeur : http://ubuntuforums.org/showthread.php?t=992706

Au cas où ils supprimeraient l'info, voici à nouveau l'info


  1. INSTALLER LES PAQUETS

  2. Installer le paquet cpulimit. Code :

    sudo apt-get install cpulimit

  3. Installer le paquet gawk. Code :

    sudo apt-get install gawk

  4. CRÉER LE FICHIER DU DÉMON CPULIMIT

Ouvrez un éditeur de texte avec des privilèges Root et sauvegardez le texte du daemon script ci-dessous dans un nouveau fichier /usr/bin/cpulimit_daemon.sh.

Code :

#!/bin/bash
# ==============================================================
# CPU limit daemon - set PID's max. percentage CPU consumptions
# ==============================================================

# Variables
CPU_LIMIT=20        # Maximum percentage CPU consumption by each PID
DAEMON_INTERVAL=3   # Daemon check interval in seconds
BLACK_PROCESSES_LIST=   # Limit only processes defined in this variable. If variable is empty (default) all violating processes are limited.
WHITE_PROCESSES_LIST=   # Limit all processes except processes defined in this variable. If variable is empty (default) all violating processes are limited.

# Check if one of the variables BLACK_PROCESSES_LIST or WHITE_PROCESSES_LIST is defined.
if [[ -n "$BLACK_PROCESSES_LIST" &&  -n "$WHITE_PROCESSES_LIST" ]] ; then    # If both variables are defined then error is produced.
   echo "At least one or both of the variables BLACK_PROCESSES_LIST or WHITE_PROCESSES_LIST must be empty."
   exit 1
elif [[ -n "$BLACK_PROCESSES_LIST" ]] ; then                                 # If this variable is non-empty then set NEW_PIDS_COMMAND variable to bellow command
   NEW_PIDS_COMMAND="top -b -n1 -c | grep -E '$BLACK_PROCESSES_LIST' | gawk '\$9>CPU_LIMIT {print \$1}' CPU_LIMIT=$CPU_LIMIT"
elif [[ -n "$WHITE_PROCESSES_LIST" ]] ; then                                 # If this variable is non-empty then set NEW_PIDS_COMMAND variable to bellow command
   NEW_PIDS_COMMAND="top -b -n1 -c | gawk 'NR>6' | grep -E -v '$WHITE_PROCESSES_LIST' | gawk '\$9>CPU_LIMIT {print \$1}' CPU_LIMIT=$CPU_LIMIT"
else
   NEW_PIDS_COMMAND="top -b -n1 -c | gawk 'NR>6 && \$9>CPU_LIMIT {print \$1}' CPU_LIMIT=$CPU_LIMIT"
fi

# Search and limit violating PIDs
while sleep $DAEMON_INTERVAL
do
   NEW_PIDS=$(eval "$NEW_PIDS_COMMAND")                                                                    # Violating PIDs
   LIMITED_PIDS=$(ps -eo args | gawk '$1=="cpulimit" {print $3}')                                          # Already limited PIDs
   QUEUE_PIDS=$(comm -23 <(echo "$NEW_PIDS" | sort -u) <(echo "$LIMITED_PIDS" | sort -u) | grep -v '^$')   # PIDs in queue

   for i in $QUEUE_PIDS
   do
       cpulimit -p $i -l $CPU_LIMIT -z &   # Limit new violating processes
   done
done
  1. MODIFIER LES VARIABLES EN FONCTION DES BESOINS DE VOTRE ENVIRONNEMENT

CPU_LIMIT Changez cette variable dans le script ci-dessus si vous souhaitez que la consommation du CPU pour chaque processus soit inférieure à 20%. Veuillez lire le chapitre "Si vous utilisez un ordinateur SMP" ci-dessous si vous avez un ordinateur SMP (plus d'un CPU ou un CPU avec plus d'un cœur).

DAEMON_INTERVAL Changez cette variable dans le script ci-dessus si vous souhaitez avoir des vérifications plus ou moins régulières. L'intervalle est en secondes et la valeur par défaut est de 3 secondes.

BLACK_PROCESS_LIST et WHITE_PROCESSES_LIST La variable BLACK_PROCESSES_LIST limite uniquement les processus spécifiés. Si la variable est vide (par défaut), tous les processus en infraction sont limités.

La variable WHITE_PROCESSES_LIST limite tous les processus sauf ceux définis dans cette variable. Si la variable est vide (par défaut), tous les processus en infraction sont limités.

L'une ou les deux variables BLACK_PROCESSES_LIST et WHITE_PROCESSES_LIST doivent être vides - il n'est pas logique que les deux variables soient définies.

Vous pouvez spécifier plusieurs processus dans l'une de ces deux variables en utilisant les caractères de délimitation "|" (sans guillemets doubles). Exemple : si vous souhaitez cpulimiter tous les processus sauf ceux de mysql, firefox et gedit, définissez la variable : WHITE_PROCESSES_LIST="mysql|firefox|gedit"

  1. PROCÉDURE POUR DÉMARRER AUTOMATIQUEMENT LE DÉMON AU DÉMARRAGE

  2. Définir les autorisations de fichiers pour l'utilisateur Root : Code :

    sudo chmod 755 /usr/bin/cpulimit_daemon.sh

  3. Ouvrez un éditeur de texte avec les privilèges de Root et enregistrez le script ci-dessous dans le nouveau fichier /etc/init.d/cpulimit.

Code :

#!/bin/sh
#
# Script to start CPU limit daemon
#
set -e

case "$1" in
start)
if [ $(ps -eo pid,args | gawk '$3=="/usr/bin/cpulimit_daemon.sh"  {print $1}' | wc -l) -eq 0 ]; then
    nohup /usr/bin/cpulimit_daemon.sh >/dev/null 2>&1 &
    ps -eo pid,args | gawk '$3=="/usr/bin/cpulimit_daemon.sh"  {print}' | wc -l | gawk '{ if ($1 == 1) print " * cpulimit daemon started successfully"; else print " * cpulimit daemon can not be started" }'
else
    echo " * cpulimit daemon can't be started, because it is already running"
fi
;;
stop)
CPULIMIT_DAEMON=$(ps -eo pid,args | gawk '$3=="/usr/bin/cpulimit_daemon.sh"  {print $1}' | wc -l)
CPULIMIT_INSTANCE=$(ps -eo pid,args | gawk '$2=="cpulimit" {print $1}' | wc -l)
CPULIMIT_ALL=$((CPULIMIT_DAEMON + CPULIMIT_INSTANCE))
if [ $CPULIMIT_ALL -gt 0 ]; then
    if [ $CPULIMIT_DAEMON -gt 0 ]; then
        ps -eo pid,args | gawk '$3=="/usr/bin/cpulimit_daemon.sh"  {print $1}' | xargs kill -9   # kill cpulimit daemon
    fi

    if [ $CPULIMIT_INSTANCE -gt 0 ]; then
        ps -eo pid,args | gawk '$2=="cpulimit" {print $1}' | xargs kill -9                    # release cpulimited process to normal priority
    fi
    ps -eo pid,args | gawk '$3=="/usr/bin/cpulimit_daemon.sh"  {print}' | wc -l | gawk '{ if ($1 == 1) print " * cpulimit daemon can not be stopped"; else print " * cpulimit daemon stopped successfully" }'
else
    echo " * cpulimit daemon can't be stopped, because it is not running"
fi
;;
restart)
$0 stop
sleep 3
$0 start
;;
status)
ps -eo pid,args | gawk '$3=="/usr/bin/cpulimit_daemon.sh"  {print}' | wc -l | gawk '{ if ($1 == 1) print " * cpulimit daemon is running"; else print " * cpulimit daemon is not running" }'
;;
esac
exit 0
  1. Changez le propriétaire du fichier en Root :

Code :

sudo chown root:root /etc/init.d/cpulimit
  1. Modifier les autorisations :

Code :

sudo chmod 755 /etc/init.d/cpulimit
  1. Ajouter script aux répertoires de la procédure de démarrage : Code :

    sudo update-rc.d cpulimit defaults

  2. Redémarrer pour vérifier si script lance le démon cpulimit au démarrage : Code :

    sudo reboot

  3. VÉRIFIER, ARRÊTER, DÉMARRER ET REDÉMARRER MANUELLEMENT LE DÉMON

Note : Daemon et service dans ce tutoriel ont la même signification.

Note : Pour les utilisateurs utilisant une version antérieure à Ubuntu 8.10 (comme Ubuntu 8.04 LTS), au lieu de la commande service, utilisez la syntaxe "sudo /etc/init.d/cpulimit status/start/stop/restart" ou installez le paquet sysvconfig en utilisant la commande : sudo apt-get install sysvconfig

Vérifier si le service cpulimit est en cours d'exécution Vérifier les retours de commande : "cpulimit daemon is running" si le service est lancé, ou "cpulimit daemon is not running" si le service n'est pas lancé. Code :

sudo service cpulimit status

Démarrer le service cpulimit Vous pouvez démarrer manuellement le démon cpulimit qui commencera à omettre la consommation du CPU. Code :

sudo service cpulimit start

Arrêter le service cpulimit La commande Stop arrête le démon cpulimit (donc aucun nouveau processus ne sera limité) et permet également à tous les processus limités existants d'avoir un accès complet au CPU, comme c'était le cas avant que cpulimit ne fonctionne. Code :

sudo service cpulimit stop

Redémarrer le service cpulimit Si vous modifiez les paramètres de certaines variables dans /usr/bin/cpulimit_daemon.sh comme CPU_LIMIT, DAEMON_INTERVAL, BLACK_PROCESSES_LIST ou WHITE_PROCESSES_LIST, alors après avoir modifié les paramètres vous devez redémarrer le service. Code :

sudo service cpulimit restart
  1. VÉRIFIER LA CONSOMMATION DE CPU AVEC OU SANS LE DÉMON CPULIMIT

Sans démon 1. arrêter le démon cpulimit (sudo service cpulimit stop) 2. exécutez des tâches gourmandes en CPU en arrière-plan 3. Exécutez la commande : top et vérifiez la colonne %CPU. Le résultat de %CPU est probablement supérieur à 20% pour chaque processus.

Avec le démon activé 1. démarrez le démon cpulimit (sudo service cpulimit start) 2. Exécutez les mêmes tâches intensives en arrière-plan. 3. exécutez la commande : top et vérifiez la colonne %CPU. Le résultat de %CPU doit être de 20% maximum pour chaque processus. Note : N'oubliez pas qu'au début, %CPU peut être supérieur à 20%, car le démon doit attraper les processus en infraction dans un intervalle de 3 secondes (défini dans script par défaut).

  1. SI UTILISATION D'ORDINATEUR SMP

J'ai testé ce code sur un ordinateur Intel à processeur double cœur - qui se comporte comme un ordinateur SMP. N'oubliez pas que la commande top et aussi cpulimit par défaut se comportent en mode Irix, où 20% signifie 20% d'un CPU. S'il y a deux CPU (ou dual-core), le %CPU total peut être de 200%. Dans la commande top, le mode Irix peut être désactivé avec la commande I (en appuyant sur +i lorsque la commande top est en cours d'exécution) et le mode Solaris est activé, où la quantité totale de CPU est divisée par le nombre de CPU, de sorte que %CPU ne peut être supérieur à 100% sur n'importe quel nombre de CPU. Veuillez lire plus d'informations sur la commande top dans la page de manuel top (recherchez la commande I). Veuillez également lire plus d'informations sur le fonctionnement de cpulimit sur les ordinateurs SMP sur la page officielle de cpulimit.

Mais comment fonctionne le démon cpulimit sur un ordinateur SMP ? Toujours en mode Irix. Ainsi, si vous souhaitez dépenser 20% de la puissance du processeur sur un ordinateur à 2 CPU, alors 40% doit être utilisé pour la variable CPU_LIMIT dans le daemon cpulimit script.

  1. DÉSINSTALLER LE DÉMON CPULIMIT ET LE PROGRAMME CPULIMIT

Si vous souhaitez vous débarrasser de cpulimit daemon, vous pouvez nettoyer votre système en supprimant cpulimit daemon et en désinstallant le programme cpulimit.

  1. Arrêter le démon cpulimit Code :

    sudo service cpulimit stop # Stop cpulimit daemon and all cpulimited processes

  2. Supprimer le daemon de la procédure de démarrage Code :

    sudo update-rc.d -f cpulimit remove # Suppression des liens symboliques

  3. Supprimer la procédure de démarrage Code :

    sudo rm /etc/init.d/cpulimit # Supprimer cpulimit boot-up script

  4. Supprimer le démon cpulimit Code :

    sudo rm /usr/bin/cpulimit_daemon.sh # Supprimer le démon cpulimit script

  5. Désinstaller le programme cpulimit Code :

    sudo apt-get remove cpulimit

  6. Désinstaller le programme gawk Si vous n'avez pas besoin de ce programme pour un autre script, vous pouvez le mettre à distance. Code :

    sudo apt-get remove gawk

  7. NOTE SUR LES AUTEURS

Je viens d'écrire un démon pour cpulimit (scripts bash ci-dessus). Je ne suis pas l'auteur du projet cpulimit. Si vous avez besoin de plus d'informations sur le programme cpulimit, veuillez lire la page web officielle de cpulimit : http://cpulimit.sourceforge.net/ .

Regards, Abcuser

0 votes

Il existe une solution pour plafonner l'utilisation, voir : bash -c "help ulimit"

0 votes

C'est loin d'être robuste, mais ça marche un peu. Dans mon cas, cela perturberait le tty si j'utilisais top Il disait qu'il n'était pas en marche alors qu'il l'était, mais sinon il a fait le travail. Merci beaucoup !

3 votes

Ulimit n'est pas une solution pour limiter les %.

6voto

Kibbee Points 36474

Pourquoi limiter le pourcentage de CPU quand on peut simplement ajuster la priorité du processus en utilisant renice ? En utilisant renice, et en définissant une priorité basse, le processus peut toujours utiliser 100% du processeur s'il est disponible, mais n'importe quel autre processus avec une priorité plus élevée obtiendra le processus quand il en aura besoin, avec presque aucun décalage perceptible.

4voto

yapa Points 21

J'ai eu un problème similaire, et les autres solutions présentées dans le fil de discussion ne le traitent pas du tout. Ma solution fonctionne pour moi pour le moment, mais elle est sous-optimale, en particulier pour les cas où le processus est détenu par Root.
Ma solution pour l'instant est d'essayer très fort de m'assurer que je n'ai pas de processus à long terme appartenant à Root (comme si la sauvegarde devait être effectuée uniquement par un utilisateur).

Je viens d'installer l'applet des capteurs matériels pour gnome, et j'ai configuré des alarmes pour les températures hautes et basses du CPU, puis j'ai configuré les commandes suivantes pour chaque alarme :

faible :

mv /tmp/hogs.txt /tmp/hogs.txt.$$ && cat /tmp/hogs.txt.$$ | xargs -n1 kill -CONT

élevé :

touch /tmp/hogs.txt && ps -eo pcpu,pid | sort -n -r | head -1 | gawk '{ print $2 }' >> /tmp/hogs.txt && xargs -n1 kill -STOP < /tmp/hogs.txt

La bonne nouvelle est que mon ordinateur ne surchauffe plus et ne tombe plus en panne. L'inconvénient est que les processus du terminal sont déconnectés du terminal lorsqu'ils sont arrêtés, et ne sont pas reconnectés lorsqu'ils reçoivent le signal CONT. L'autre problème est que si un programme interactif est à l'origine de la surchauffe (comme un certain plugin de navigateur Web !), il se fige au milieu de ce que je suis en train de faire en attendant que le CPU refroidisse. Il serait plus agréable que la mise à l'échelle du CPU prenne en charge ce problème à un niveau global, mais le problème est que je n'ai que deux paramètres sélectionnables sur mon CPU et que le paramètre lent n'est pas assez lent pour empêcher la surchauffe.

Je le répète, cela n'a rien à voir avec la priorité des processus, le re-nicing, et évidemment rien à voir avec l'arrêt des travaux qui durent longtemps. Il s'agit d'empêcher l'utilisation du CPU de rester à 100% pendant trop longtemps, parce que le matériel est incapable de dissiper la chaleur assez rapidement lorsqu'il fonctionne à pleine capacité (un CPU inactif génère moins de chaleur qu'un CPU pleinement chargé).

D'autres possibilités évidentes qui pourraient aider sont :

Réduire la vitesse globale du CPU dans le BIOS

Remplacez le dissipateur thermique ou réappliquez le gel thermique pour voir si cela aide.

Nettoyez le dissipateur thermique avec de l'air comprimé.

Remplacer le ventilateur du CPU

[modifier] Note : plus de surchauffe à 100% du CPU lorsque je désactive la vitesse variable du ventilateur dans le bios (asus p5q pro turbo). Avec le CPU à pleine charge, chaque cœur plafonne à 49 degrés Celsius.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X