Puoi usare /proc/$PID/task
per trovare tutti i thread di un dato processo, quindi puoi usare
$ ls /proc/$PID/task | xargs renice $PRIO
a renice
tutti i thread appartenenti a un determinato processo.
Allo stesso modo /proc/$PID/task/$PID/children
può essere utilizzato per trovare tutti i processi figlio (o /proc/$PID/task/*/children
se vuoi tutti i processi figlio di tutti i thread di un determinato processo).
$ cat /proc/$PID/task/$PID/children | xargs renice $PRIO
$ cat /proc/$PID/task/*/children | xargs renice $PRIO
Trovare tutti i PID a renice
ricorsivamente
Abbiamo bisogno di ottenere i PID di tutti i processi ("normali" o "thread") che sono discendenti (figli o nel gruppo di thread) del processo da nicciare. Questo dovrebbe essere ricorsivo (considerando i figli dei bambini).
Anton Leontiev risposta dà il suggerimento per farlo:tutti i nomi delle cartelle in /proc/$PID/task/
sono i PID dei thread contenenti un children
file che elenca potenziali processi figli.
Tuttavia, manca di ricorsività, quindi ecco uno script di shell veloce e sporco per trovarli:
#!/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
Se il processo PID 1234 è quello che vuoi rendere ricorsivamente carino, ora puoi fare:
renice -n 15 -p $(/path/to/findchildren.sh 1234)
Note a margine
Buon valore o quote di CPU?
Tieni presente che al giorno d'oggi i valori piacevoli potrebbero non essere così rilevanti "a livello di sistema", a causa del raggruppamento automatico delle attività, specialmente quando si utilizza systemd . Consulta questa risposta per maggiori dettagli.
Differenza tra thread e processi
Nota:questa risposta spiega con precisione i thread di Linux.
In breve:il kernel gestisce solo "entità eseguibili", cioè qualcosa che può essere eseguito e programmato . Dal punto di vista del kernel, queste entità sono chiamate processi. Un thread è solo un tipo di processo che condivide (almeno) spazio di memoria e gestori di segnali con un altro. Ciascuno di questi processi ha un identificatore univoco a livello di sistema:il PID (ID processo).
Di conseguenza, puoi renice
ogni "thread" individualmente perché hanno il loro proprio PID.
Vedi questa risposta per ulteriori informazioni su PID (ProcessID) e differenza TID (ThreadID).
Non dobbiamo confondere il PID del processo e l'id del thread talvolta scritto TID o nel comando ps LPW. L's
Il comando ha opzioni per visualizzare i thread e sotto top
o htop
si passa da un thread all'altro e si elabora con il H
lettera. Come detto in precedenza da @Totor, con NPTL, che è l'attuale implementazione con kernel> 2.6, tutti i thread hanno lo stesso pid, ma hanno un tid distinto. Mostri tutti i thread di un processo tramite:
$ ps -Ljf <pid>
Questi tid sono i nomi delle directory sotto /proc/<pid>/task
, e anche se renice(1) dire che il suo argomento predefinito è un pid quando applicato a un pid renice solo il thread principale (questo è un bug nell'implementazione di Linux come scritto in setpriority(2) ), si può applicare anche ad un tid e ne rifinisce il filo. Ecco perché la risposta di @Anton è valida.
Ma molto spesso esiste un modo più semplice per ottenere il risultato desiderato, tutti questi thread condividono lo stesso pgid che è il pid del leader del gruppo; puoi renice tramite pgid immettendo:
$ renice -g <pgid>
Se non vuoi rifinire qualche altro processo che dipende dallo stesso capogruppo, devi usare la ricetta di @Anton:
$ renice <priority> $(ls -1 /proc/<pid>/task)
oppure:
$renice <priority> $(ps --no-header -Lo tid <pid>)
Potresti anche voler sapere quali sono gli altri processi dello stesso gruppo rispetto al processo che vuoi renice, cioè i processi che condividono lo stesso pgid. Puoi usare ps(1) , ps
non permette di selezionare i processi per capogruppo, ma puoi grep a ps
per farlo. I processi con pgid 1908
sarà dato dal comando:
$ ps --no-header axo pid,pgid |sed -n '/^ *[0-9][0-9]* *1908/s/[0-9][0-9]* *$//p'
o se preferisci awk a sed:
$ ps --no-header axo pid,pgid|awk '{if ($2=="1908") print $1;}'