Linux ne suit pas (encore) la norme POSIX.1 qui dit qu'un renice
sur un processus affecte "tous les threads de portée système dans le processus", car selon le doc pthreads (7) "les threads ne partagent pas une belle valeur commune".
Cependant, parfois, il peut être commode de renice
«tout» lié à un processus donné (un exemple serait les processus enfants Apache et tous leurs threads). Alors,
- comment puis-je
renice
tous les threads appartenant à un processus donné? - comment puis-je
renice
tous les processus enfants appartenant à un processus donné?
Je recherche une solution assez simple.
Je sais que les groupes de processus peuvent parfois être utiles, mais ils ne correspondent pas toujours à ce que je veux faire: ils peuvent inclure un ensemble de processus plus large ou différent.
Utiliser un cgroup
géré par systemd
peut aussi être utile, mais même si cela m'intéresse, je recherche surtout une solution "standard".
EDIT: aussi, man (7) pthreads
dit "tous les threads d'un processus sont placés dans le même groupe de threads; tous les membres d'un groupe de threads partagent le même PID". Alors, est-il même possible de renice
quelque chose qui n'a pas son propre PID?
man (7) pthreads
dit à propos de l'implémentation actuelle (NPTL): "tous les threads d'un processus sont placés dans le même groupe de threads; tous les membres d'un groupe de threads partagent le même PID" et "Les threads ne partagent pas une valeur commune". Alors, comment pouvez-vous retailler un thread qui n'a pas son propre PID, quandrenice
utilise un PID pour le faire?24995 (process ID) old priority 0, new priority -10
. 24995 n'apparaît pas dansps
, donc ce n'est pas un processus. Peut-être que les threads de retouche fonctionnent réellement?Belle valeur ou parts de CPU?
Veuillez noter que de nos jours, les bonnes valeurs peuvent ne pas être aussi pertinentes "à l'échelle du système", en raison du regroupement automatique des tâches, surtout lorsque vous utilisez systemd . Veuillez consulter cette réponse pour plus de détails.
Différence entre les threads et les processus
Question importante sous Linux, car la documentation perpétue les doutes (sur les threads n'ayant pas leur propre PID par exemple).
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écuté et planifié . Du point de vue 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 (Process ID). Pour les soi-disant threads, il est parfois appelé TID (Thread ID), mais du point de vue sysadmin (et du noyau!), TID et PID sont la même chose (ils partagent le même espace de noms).
En conséquence, vous pouvez
renice
chaque "thread" individuellement car ils ont leur propre PID 1 .Recherche de tous les PID à
renice
récursive deNous devons obtenir les PID de tous les processus ("normaux" ou "thread") qui sont descendants (enfants ou dans le groupe de threads) du processus à mettre en réseau. Cela devrait être récursif (compte tenu des enfants des enfants).
La réponse d' Anton Leontiev donne l'astuce pour le faire: tous les noms de dossiers
/proc/$PID/task/
sont des PID de threads contenant unchildren
fichier répertoriant les processus enfants potentiels.Cependant, il manque de récursivité, alors voici un script shell rapide et sale pour les trouver:
Si le processus PID 1234 est celui que vous souhaitez utiliser de manière récursive, vous pouvez maintenant faire:
1 Notez que, pour la conformité POSIX, l'appel
getpid(2)
dans un thread ne vous donnera pas l'ID unique (PID) à l'échelle du système de cette entité exécutable, mais plutôt le PID du processus principal dans le "groupe de threads". Vous auriez besoin d'appeler à lagettid(2)
place. Voir cette réponse pour plus d'informations.la source
Nous ne devons pas confondre le processus PID et l'ID de thread parfois écrit TID ou dans la commande ps LPW. La
s
commande a des options pour afficher les threads, et soustop
ouhtop
vous basculez entre les threads et traitez par laH
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 montrez tous les fils d'un processus en:Ces tid sont les noms des répertoires sous
/proc/<pid>/task
, et même si renice (1) dit que son argument par défaut est un pid lorsqu'il est appliqué à un pid, il ne renice que le thread principal (c'est un bug dans l'implémentation linux comme écrit dans setpriority (2 ) ), il peut également être appliqué à un tid et il renice le fil. C'est pourquoi la réponse de @Anton est valide.Mais le plus souvent, il existe un moyen plus facile d'obtenir le résultat souhaité, tous ces threads partagent le même pgid qui est le pid du chef de groupe; vous pouvez renice par pgid en émettant:
Si vous ne voulez pas modifier un autre processus qui dépend du même chef de groupe, vous devez utiliser la recette @ Anton:
ou:
Vous voudrez peut-être également savoir quels sont les autres processus du même groupe que le processus que vous souhaitez renice, 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 aps
pour le faire. Les processus avec pgid1908
seront donnés par la commande:ou si vous préférez awk à sed:
la source
$ renice -n 18 -g 8524 renice: failed to get priority for 8524 (process group ID): No such process $ ps --no-header axo pid,pgid|awk '{if ($2=="8524") print $1;}'
que la méthode de Totor fonctionne / fonctionne toujours:$ /bin/ls /proc/8524/task | /usr/bin/xargs renice 19 2739 (process ID) old priority 19, new priority 19 2740 (process ID) old priority 19, new priority 19 ...
j'ai confirmé avec / proc, htop, pstree, etc. que j'ai le bon top- PID de niveau. Peut-être que quelque chose a changé au cours de la dernière année./proc/8524/task
maisrenice -g
échouez. Lorsque vous regardez une arborescence de processus, une branche se trouve dans le même groupe de processus, pas seulement un processus threadé. Essayez à nouveau de vérifier le résultat deps -Ljf
.Je voudrais recommander d'utiliser l'argument -g (groupes de processus) au lieu de -p (identificateurs de processus) lors de l'utilisation de renice. Il fait la même chose sans bash-foo.
c'est à dire
la source
Voici un de mes scripts:
la source