GNU/Linux >> Linux Esercitazione >  >> Linux

Come modificare tutti i thread (e i figli) di un processo su Linux?

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

Linux
  1. Come avviare il comando Linux in background e scollegare il processo nel terminale

  2. Come impostare la priorità del processo Linux usando i comandi nice e renice

  3. Come posso rinominare tutte le cartelle e i file in minuscolo su Linux?

  4. Renice:Come cambiare tutti i thread?

  5. Linux:come sapere dove è stato avviato un processo e come è stato avviato?

Come sospendere un processo e riprenderlo in un secondo momento in Linux

Come lavorare con il processo in primo piano e in background in Linux

Come ottenere l'utilizzo della CPU di un singolo processo in Linux

Come trovare il PID e il PPID di un processo in Linux

Come uccidere i processi in Linux usando kill, killall e pkill

Come tracciare e tracciare un processo Linux