web-dev-qa-db-fra.com

Mieux Nice: comment puis-je suspendre complètement un processus exigeant si l'ordinateur est unidle?

Certains travaux en arrière-plan sur mon PC font un traitement lourd. Les exécuter avec un niveau de Nice maximum produit toujours une interactivité lente et m'agace.

Existe-t-il un meilleur moyen que le maximum agréable?

Dès que j'utilise le PC, je veux que le travail en arrière-plan s'arrête. Cela peut continuer si je n'utilise pas le PC pendant environ cinq minutes.

Le travail d'arrière-plan n'a pas de date limite. Si cela n'a pas d'importance si cela prend beaucoup plus de temps.

Le travail que je veux ralentir est un processus d'encodage vidéo qui utilise un thread par CPU. Sur mon ordinateur portable, il y a 4 threads produisant une charge de 400%.

3
guettli

Une façon alternative de gérer (suspendre) un processus exigeant pendant que l'ordinateur est utilisé

J'ai testé le script ci-dessous en combinaison avec kdenlive, rendant une grande vidéo. Dans les tests, cela a bien fonctionné. Le script (en arrière-plan) lui-même ne consomme pratiquement aucune ressource. La seule chose qu'il fait est de vérifier une fois toutes les 5 secondes si le processus ciblé s'exécute. Si c'est le cas, il vérifiera le temps d'inactivité actuel. Les deux ne signifient rien pour votre système

Le script est basé sur l'utilisation de xprintidle. xprintidle garde une trace des événements du clavier et de la souris et mesure le temps pendant lequel il n'y a pas eu d'activité. Si le processus exigeant démarre, il est immédiatement mis en pause (puisque l'ordinateur est évidemment utilisé) avec la commande:

kill -STOP <pid>

Si, par la suite, le temps d'inactivité dépasse une certaine limite de temps (arbitraire), le processus est repris, en utilisant la commande:

kill -CONT <pid>

Par la suite, si le temps d'inactivité revient en dessous de la limite de temps définie, le processus est à nouveau suspendu, etc.

enter image description here

utilisation du processeur avant/pendant/après le temps d'inactivité, rendu d'une grande vidéo avec kdenlive en utilisant la fusion

À propos de kill -STOP et kill -CONT

Bien que les arguments -STOP et -CONT sont mentionnés dans man kill, ce n'est pas expliqué, étrangement. Cependant, par exemple ici nous pouvons lire ce qu'il fait:

Fondamentalement kill -STOP 1234 interrompra le processus avec pid 1234, et kill -CONT 1234 le reprendra. C'est comme si vous pouviez mettre en veille des applications individuelles au lieu de la totalité de votre ordinateur.

Ainsi, le processus exigeant est mis en veille pendant que l'ordinateur est utilisé (inactif).

Recherche du processus à suspendre

Le script s'exécute avec le nom du processus (vous aimeriez être suspendu si vous utilisez l'ordinateur) comme argument.

L'astuce consiste à trouver le bon processus à suspendre. Ce ne sera pas le nom de votre éditeur vidéo, car il utilisera certainement des outils externes pour le rendu. Dans mon cas, kdenlive a utilisé melt. Le script a interrompu avec succès melt et a repris le rendu après un temps d'inactivité défini.

Vous pouvez utiliser la commande top si vous n'êtes pas sûr du nom du processus. Exécutez top dans un terminal et appuyez sur Ctrl+M pour trier sur l'utilisation de la mémoire. Le processus exigeant sera au sommet.

Le script

#!/usr/bin/env python3
import subprocess
import time
import sys

limit = int(sys.argv[1])
proc = sys.argv[2]

def get(command):
    return subprocess.check_output(command).decode("utf-8").strip()

def check_runs(proc):
    try:
        return get(["pgrep", proc])
    except subprocess.CalledProcessError:
        pass

pid1 = check_runs(proc)
t1 = int(int(get("xprintidle"))/1000)

while True:
    time.sleep(5)
    pid2 = check_runs(proc)
    # (only) if the process exists, manage its activity
    if pid2 != None:
        t2 = int(int(get("xprintidle"))/1000)
        # if the process just started, obviously the system is not idle ->
        # pause the process (try in case it was killed by user in between):
        if pid1 == None:
            try:
                subprocess.Popen(["kill", "-STOP", pid2])
            except subprocess.CalledProcessError:
                pass
        # If there is a change in time status (breaktime entered or ended)
        else:              
            if [t2 > limit, t1 > limit].count(True) == 1:
                if t2 > limit:
                    cmd = ["kill", "-CONT", pid2]
                else:
                    cmd = ["kill", "-STOP", pid2]
                subprocess.Popen(cmd)
        t1 = t2
    pid1 = pid2

Comment utiliser

  • Le script a besoin de xprintidle

    Sudo apt-get instal xprintidle
    
  • Copiez le script ci-dessus dans un fichier vide, enregistrez-le sous manage_proc.py

  • Testez-le par la commande

    python3 /path/to/manage_proc.py <seconds> <process_name>
    

    <seconds> est le temps d'inactivité en secondes avant que vous ne souhaitiez que votre processus démarre.
    Démarrage du processus consommateur après démarrage du script.

  • Si tout fonctionne bien, ajoutez le script aux applications de démarrage: Dash> Applications de démarrage> Ajouter la commande:

     python3 /path/to/manage_proc.py <seconds> <process_name>
    
8
Jacob Vlijm