Puedes usar /proc/$PID/task
para encontrar todos los subprocesos de un proceso dado, por lo tanto, puede usar
$ ls /proc/$PID/task | xargs renice $PRIO
a renice
todas las subprocesos pertenecientes a un proceso dado.
De la misma manera /proc/$PID/task/$PID/children
se puede usar para encontrar todos los procesos secundarios (o /proc/$PID/task/*/children
si desea todos los procesos secundarios de todos los hilos de un proceso dado).
$ cat /proc/$PID/task/$PID/children | xargs renice $PRIO
$ cat /proc/$PID/task/*/children | xargs renice $PRIO
Encontrar todos los PID hasta renice
recursivamente
Necesitamos obtener los PID de todos los procesos ("normales" o "subprocesos") que son descendientes (secundarios o en el grupo de subprocesos) del proceso a ser modificado. Esto debería ser recursivo (considerando los hijos de los niños).
Antón Leóntiev answer's da la pista para hacerlo:todos los nombres de carpetas en /proc/$PID/task/
son PID de hilos que contienen un children
archivo que enumera los posibles procesos secundarios.
Sin embargo, carece de recursividad, por lo que aquí hay un script de shell rápido y sucio para encontrarlos:
#!/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 el proceso PID 1234 es el que desea que sea agradable recursivamente, ahora puede hacer:
renice -n 15 -p $(/path/to/findchildren.sh 1234)
Notas al margen
¿Buen valor o recursos compartidos de CPU?
Tenga en cuenta que hoy en día, los valores agradables pueden no ser tan relevantes "en todo el sistema", debido a la agrupación automática de tareas, especialmente cuando se usa systemd . Consulte esta respuesta para obtener más detalles.
Diferencia entre hilos y procesos
Nota:esta respuesta explica los subprocesos de Linux con precisión.
En resumen:el kernel solo maneja "entidades ejecutables", es decir, algo que se puede ejecutar y programado . En cuanto al kernel, estas entidades se denominan procesos. Un subproceso es solo un tipo de proceso que comparte (al menos) espacio de memoria y controladores de señales con otro. Cada uno de estos procesos tiene un identificador único en todo el sistema:el PID (ID del proceso).
Como resultado, puede renice
cada "hilo" individualmente porque tienen sus propios ID.
Consulte esta respuesta para obtener más información sobre PID (ProcessID) y la diferencia de TID (ThreadID).
No debemos confundir el PID del proceso y el id del subproceso en algún momento escrito TID o en el comando ps LPW. El s
El comando tiene opciones para mostrar hilos y bajo top
o htop
cambias entre subprocesos y procesos por el H
carta. Como dijo @Totor anteriormente, con NPTL, que es la implementación actual con kernel> 2.6, todos los subprocesos tienen el mismo pid, pero tienen un tid distinto. Muestras todos los subprocesos de un proceso mediante:
$ ps -Ljf <pid>
Estos tid son los nombres de los directorios bajo /proc/<pid>/task
, e incluso si renice(1) digamos que su argumento predeterminado es un pid cuando se aplica a un pid, solo modifica el hilo principal (este es un error en la implementación de Linux como está escrito en setpriority(2) ), también se puede aplicar a un tid y refina el hilo. Por eso la respuesta de @Anton es válida.
Pero la mayoría de las veces hay una manera más fácil de lograr el resultado deseado, todos estos subprocesos comparten el mismo pgid que es el pid del líder del grupo; puede renice por pgid emitiendo:
$ renice -g <pgid>
Si no quieres renice algún otro proceso que depende del mismo líder del grupo, tienes que usar la receta de @Anton:
$ renice <priority> $(ls -1 /proc/<pid>/task)
o:
$renice <priority> $(ps --no-header -Lo tid <pid>)
También puede querer saber cuáles son los otros procesos del mismo grupo que el proceso que desea renice, es decir, los procesos que comparten tiene el mismo pgid. Puede usar ps(1) , ps
no permite seleccionar procesos por líder de grupo, pero puede grep un ps
para hacerlo. Los procesos con pgid 1908
será dado por el comando:
$ ps --no-header axo pid,pgid |sed -n '/^ *[0-9][0-9]* *1908/s/[0-9][0-9]* *$//p'
o si prefiere awk a sed:
$ ps --no-header axo pid,pgid|awk '{if ($2=="1908") print $1;}'