GNU/Linux >> Tutoriels Linux >  >> Linux

Comment renicer tous les threads (et enfants) d'un processus sous Linux ?

Vous pouvez utiliser /proc/$PID/task pour trouver tous les threads d'un processus donné, vous pouvez donc utiliser

$ ls /proc/$PID/task | xargs renice $PRIO

à renice tous les threads appartenant à un processus donné.

Idem /proc/$PID/task/$PID/children peut être utilisé pour trouver tous les processus enfants (ou /proc/$PID/task/*/children si vous voulez tous les processus enfants de tous les threads d'un processus donné).

$ cat /proc/$PID/task/$PID/children | xargs renice $PRIO
$ cat /proc/$PID/task/*/children | xargs renice $PRIO

Trouver tous les PID jusqu'à renice récursivement

Nous devons obtenir les PID de tous les processus ("normal" ou "thread") qui sont descendants (enfants ou dans le groupe de threads) du processus à traiter. Cela devrait être récursif (en tenant compte des enfants des enfants).

Anton Léontiev la réponse donne l'indice pour le faire :tous les noms de dossier dans /proc/$PID/task/ sont les PID des threads contenant un children fichier listant les processus enfants potentiels.

Cependant, il manque de récursivité, alors voici un script shell rapide et sale pour les trouver :

#!/bin/sh
[ "$#" -eq 1 -a -d "/proc/$1/task" ] || exit 1

PID_LIST=
findpids() {
        for pid in /proc/$1/task/* ; do
                pid="$(basename "$pid")"
                PID_LIST="$PID_LIST$pid "
                for cpid in $(cat /proc/$1/task/$pid/children) ; do
                        findpids $cpid
                done
        done
}

findpids $1
echo $PID_LIST

Si le processus PID 1234 est celui que vous voulez récursivement agréable, vous pouvez maintenant faire :

renice -n 15 -p $(/path/to/findchildren.sh 1234)

Notes annexes

Belle valeur ou parts de CPU ?

Veuillez noter qu'aujourd'hui, les valeurs agréables peuvent ne pas être aussi pertinentes "à l'échelle du système", en raison du regroupement automatique des tâches, en particulier lors de l'utilisation de systemd . Veuillez consulter cette réponse pour plus de détails.

Différence entre les threads et les processus

Remarque :cette réponse explique précisément les threads Linux.

En bref :le noyau ne gère que les "entités exécutables", c'est-à-dire quelque chose qui peut être exécutable et prévu . Au niveau du noyau, ces entités sont appelées processus. Un thread est juste une sorte de processus qui partage (au moins) l'espace mémoire et les gestionnaires de signaux avec un autre. Chacun de ces processus possède un identifiant unique à l'échelle du système :le PID (ID de processus).

Par conséquent, vous pouvez renice chaque "thread" individuellement car ils ont leur propre PID.

Voir cette réponse pour plus d'informations sur la différence PID (ProcessID) et TID (ThreadID).


Il ne faut pas confondre le PID du processus et l'id du thread parfois écrit TID ou dans la commande ps LPW. Le s la commande a des options pour afficher les threads, et sous top ou htop vous basculez entre les threads et traitez par le H lettre. Comme indiqué précédemment par @Totor, avec NPTL, qui est l'implémentation actuelle avec le noyau> 2.6, tous les threads ont le même pid, mais ils ont un tid distinct. Vous affichez tous les threads d'un processus en :

$ ps -Ljf <pid>

Ces tid sont les noms des répertoires sous /proc/<pid>/task , et même si renice(1) disons que son argument par défaut est un pid lorsqu'il est appliqué à un pid il renice uniquement le thread principal (c'est un bogue dans l'implémentation Linux comme écrit dans setpriority(2) ), il peut également être appliqué à un tid et il raffine le fil. C'est pourquoi la réponse de @Anton est valide.

Mais le plus souvent il existe un moyen plus simple d'atteindre le résultat souhaité, tous ces threads partagent le même pgid qui est le pid du chef de groupe; vous pouvez renoncer par pgid en émettant :

$ renice -g <pgid>

Si vous ne voulez pas renoncer à un autre processus qui dépend du même chef de groupe, vous devez utiliser la recette d'@Anton :

$ renice <priority> $(ls -1 /proc/<pid>/task)

ou :

$renice <priority> $(ps --no-header -Lo tid <pid>)

Vous voudrez peut-être aussi savoir quels sont les autres processus du même groupe que le processus que vous souhaitez renicer, c'est-à-dire les processus qui partagent le même pgid. Vous pouvez utiliser ps(1) , ps ne permet pas de sélectionner les processus par chef de groupe, mais vous pouvez grep un ps pour le faire. Les processus avec le pgid 1908 sera donné par la commande :

$ ps --no-header axo pid,pgid |sed -n '/^ *[0-9][0-9]*  *1908/s/[0-9][0-9]* *$//p'

ou si vous préférez awk à sed :

$ ps --no-header axo pid,pgid|awk '{if ($2=="1908") print $1;}'

Linux
  1. Comment démarrer la commande Linux en arrière-plan et détacher le processus dans le terminal

  2. Linux - Comment limiter un processus à un seul cœur de processeur sous Linux ??

  3. Comment définir l'ID de processus sous Linux pour un programme spécifique

  4. Comment puis-je enregistrer tous les lancements de processus sous Linux ?

  5. Linux :Comment savoir où un processus a été démarré et comment il a été démarré ?

Comment suspendre un processus et le reprendre plus tard sous Linux

Comment travailler avec le processus de premier plan et d'arrière-plan sous Linux

Comment obtenir l'utilisation du processeur d'un seul processus sous Linux

Comment trouver le PID et le PPID d'un processus sous Linux

Comment tuer les processus sous Linux en utilisant kill, killall et pkill

Comment suivre et tracer un processus Linux