Linux ne suive pas (encore) la norme POSIX.1 qui dit qu'un renice
sur un processus affecte "tous les filets de portée du système dans le processus", car selon la = Pthreads (7) Doc "Les threads ne partagent pas une belle valeur commune".
Cependant, parfois, il peut être pratique pour renice
"tout" lié à un processus donné (un exemple serait des processus enfants Apache et tous leurs discussions). Donc,
renice
tout threads appartenant à un processus donné?renice
tout processus enfant appartenant à un processus donné?Je cherche une solution assez facile.
Je sais que Groupes de processus Peut parfois être utile, cependant, ils ne correspondent pas toujours à ce que je veux faire: ils peuvent inclure un ensemble de processus plus large ou différent.
L'utilisation d'un cgroup
géré par systemd
pourrait aussi être utile, mais même si je suis intéressé à en entendre parler, je cherche principalement une solution "standard".
EDIT: En outre, man (7) pthreads
dit "Tous les fils d'un processus sont placés dans le même groupe thread; tous les membres d'un groupe de threads partagent le même PID". Alors, est-ce même possible à renice
quelque chose qui n'a pas sa propre pid?
Veuillez noter que de nos jours, de belles valeurs peuvent ne pas être si pertinentes "système à l'échelle du système", en raison du groupe de tâches automatiques, espacialement lors de l'utilisation SystemD. S'il vous plaît voir cette réponse Pour plus de détails.
Question importante sur Linux, car la documentation perpétue des doutes (sur les threads ne présentant pas leur propre PID par exemple).
Remarque: cette réponse explique précisément des threads Linux.
En bref: le noyau ne traite que des "entités runnables", c'est-à-dire quelque chose qui peut être exécuter et programmé. Bernel Sage, ces entités s'appellent des processus. Un thread, n'est qu'une sorte de processus qui partage (au moins) espace mémoire et des gestionnaires de signaux avec un autre.
Tous ces processus ont un identifiant unique à l'échelle du système: le PID (ID de processus). Pour les soi-disant threads, il est parfois appelé TID (ID de fil), mais à partir du point de vue Sysadmin (et du noyau!), Tid et PID sont la même chose (ils partagent la même espace de noms).
En conséquence, vous peut renice
chaque "thread" individuellement, car ils ont leur PID1.
renice
récursivementNous devons obtenir les PID de tous les processus ("normaux" ou "thread") qui sont descendants (enfants ou dans le groupe de fil) du processus à être soigné. Cela devrait être récursif (compte tenu des enfants des enfants).
Anton Leontiev Réponse's's's's's's's's's's's's's's's's's's's Pour le faire: Tous les noms de dossiers dans /proc/$PID/task/
Sont des threads 'PID contenant un children
répertorie des processus potentiels pour enfants potentiels.
Cependant, il manque de récursivité, alors voici un script de 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)
1 Notez que, pour la conformité de POSIX, appelez getpid(2)
dans un thread sera non Donne-vous l'ID unique à l'échelle du système (PID) de cette entité annulable, mais plutôt du PID de le processus principal dans le "groupe de thread". Vous auriez besoin d'appeler gettid(2)
à la place. Voir cette réponse pour plus d'informations.
Vous pouvez utiliser /proc/$PID/task
Pour trouver tous les discussions d'un processus donné, vous pouvez donc utiliser
$ ls /proc/$PID/task | xargs renice $PRIO
à renice
tous threads appartenant à un processus donné.
De la même façon /proc/$PID/task/$PID/children
peut être utilisé pour trouver tous processus enfants (ou /proc/$PID/task/*/children
Si vous voulez tous processus enfant de tous -threads d'un processus donné).
$ cat /proc/$PID/task/$PID/children | xargs renice $PRIO
$ cat /proc/$PID/task/*/children | xargs renice $PRIO
Nous ne devrions pas confondre le processus PID et l'ID de thread de la TID ou dans la commande PS LPW. Le s
command a des options pour afficher des threads et sous top
ou htop
Vous basculez entre les threads et le processus par la lettre H
. Comme indiqué précédemment par @totor, avec NPTL, qui est la mise en œuvre actuelle avec le noyau> 2.6, toutes les threads ont le même PID, mais ils ont une TID distincte. Vous montrez tous les discussions d'un processus par:
$ ps -Ljf <pid>
Ces enfants sont les noms des répertoires sous /proc/<pid>/task
, et même si Renise (1) Dis dire que son argument par défaut est un PID lorsqu'il est appliqué à un PID, il ne s'agit que du fil principal (ceci est Un bogue dans la mise en oeuvre de Linux comme écrit dans SETPIRIORITY (2) ), il peut également être appliqué à un TID et il règne le fil. C'est pourquoi la réponse de @anton est valide.
Mais le plus souvent, il existe un moyen plus facile d'atteindre le résultat souhaité, tous ces threads partagent le même PGID qui est le PID du chef de groupe; Vous pouvez reniser par PGID en émettant:
$ renice -g <pgid>
Si vous ne voulez pas reniser un autre processus qui dépend du même chef de groupe, vous devez utiliser la recette de @ 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 reniser, c'est-à-dire les processus qui partagent ont le même PGID. Vous pouvez utiliser PS (1) , ps
_ ne permet pas de sélectionner des processus par leader du groupe, mais vous pouvez grep A ps
pour le faire. Les processus avec 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;}'
Selon man renice
(emphasis mine):
renice
modifie la priorité de planification d'un ou de plusieurs processus de fonctionnement. Le premier argument est la valeur de priorité à utiliser. Les autres arguments sont interprétés comme ID de processus (par défaut), ID de groupe de processus, ID utilisateur ou noms d'utilisateur. (...)
Et en effet, man pgrep
démontre, comme exemple:
Exemple 4: Faites tout chrome processus fonctionnant mieux:
$ renice +4 $(pgrep chrome)
Selon ceux-ci, vous pouvez combiner renice
avec pgrep
's -w | --lightweight
Switch to Renise Tous les threads à la fois, comme ça:
renice <priority> $(pgrep -w <process_name>)
Et à Renice Tous les processus enfants:
renice <priority> $(pgrep -P $(pgrep <process_name>))
Remarquez que vous pouvez également utiliser -f
Commutateur avec pgrep
Pour interroger non seulement le nom du processus, mais la ligne de commande complète (ne doit pas nécessairement être une correspondance complète).
J'aimerais vous recommander d'utiliser l'argument -g (groupes de processus) au lieu de la -p (ID de processus) tout en utilisant RENICE. C'est la même chose sans Bash-foo.
c'est à dire.
(Sudo) renice -n <NEW_PRIORITY> -g <MAIN_PROCESS_ID>