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;}'