O Linux ainda não segue o padrão POSIX.1, que diz que um renice
processo afeta "todos os encadeamentos do escopo do sistema no processo", porque de acordo com o documento pthreads (7) "os segmentos não compartilham um valor legal comum".
No entanto, às vezes, pode ser conveniente renice
"tudo" relacionado a um determinado processo (um exemplo seria os processos filhos do Apache e todos os seus threads). Tão,
- como posso
renice
todos os threads pertencentes a um determinado processo? - como posso
renice
todos os processos filhos pertencentes a um determinado processo?
Estou procurando uma solução bastante fácil.
Sei que os grupos de processos às vezes podem ser úteis, no entanto, eles nem sempre correspondem ao que eu quero fazer: eles podem incluir um conjunto de processos mais amplo ou diferente.
Usar um cgroup
gerenciado por systemd
também pode ser útil, mas mesmo que eu esteja interessado em ouvir sobre isso, estou procurando principalmente uma solução "padrão".
EDIT: também man (7) pthreads
diz que "todos os threads em um processo são colocados no mesmo grupo de threads; todos os membros de um grupo de threads compartilham o mesmo PID". Então, é possível renice
algo que não tenha seu próprio PID?
man (7) pthreads
diz sobre a implementação atual (NPTL): "todos os threads em um processo são colocados no mesmo grupo de threads; todos os membros de um grupo de threads compartilham o mesmo PID" e "Threads não compartilham um valor legal comum". Então, como você pode renomear um thread que não possui seu próprio PID, quandorenice
usa um PID para fazer isso?24995 (process ID) old priority 0, new priority -10
. 24995 não apareceps
, portanto não é um processo. Talvez os threads de renovação sejam realmente úteis?Valor agradável ou compartilhamentos de CPU?
Observe que hoje em dia, valores agradáveis podem não ser tão relevantes "em todo o sistema", devido ao agrupamento automático de tarefas, espacialmente ao usar systemd . Por favor, veja esta resposta para mais detalhes.
Diferença entre threads e processos
Pergunta importante no Linux, porque a documentação perpetua dúvidas (sobre threads que não possuem seu próprio PID, por exemplo).
Nota: esta resposta explica os threads do Linux com precisão.
Em resumo: o kernel lida apenas com "entidades executáveis", ou seja, algo que pode ser executado e agendado . Em termos de kernel, essas entidades são chamadas de processos. Um encadeamento é apenas um tipo de processo que compartilha (pelo menos) espaço de memória e manipuladores de sinal com outro.
Todo processo desse tipo possui um identificador exclusivo em todo o sistema: o PID (ID do processo). Para os chamados encadeamentos, às vezes é chamado TID (ID do encadeamento), mas do ponto de vista do sysadmin (e do kernel!), TID e PID são a mesma coisa (eles compartilham o mesmo espaço de nome).
Como resultado, você pode
renice
"encadear" individualmente porque eles têm seu próprio PID 1 .Localizando todos os PIDs para
renice
recursivaPrecisamos obter os PIDs de todos os processos ("normais" ou "encadeamentos") que são descendentes (filhos ou no grupo de encadeamentos) do processo a ser percebido. Isso deve ser recursivo (considerando os filhos das crianças).
As respostas de Anton Leontiev dão a dica para fazer isso: todos os nomes de pastas
/proc/$PID/task/
são PID de threads contendo umchildren
arquivo que lista os possíveis processos filhos.No entanto, falta recursividade, então aqui está um script shell rápido e sujo para encontrá-los:
Se o processo PID 1234 é o que você deseja, recursivamente agradável, agora você pode fazer:
1 Observe que, para conformidade com o POSIX, a chamada
getpid(2)
em um encadeamento não fornecerá o PID (ID exclusivo para todo o sistema) dessa entidade executável, mas o PID do processo principal no "grupo de encadeamentos". Você precisaria ligar emgettid(2)
vez disso. Veja esta resposta para mais informações.fonte
Não devemos confundir o PID do processo e o ID do thread em algum momento escrito TID ou no comando ps LPW. O
s
comando possui opções para exibir threads e, abaixotop
ou abaixo,htop
você alterna entre threads e processo pelaH
letra. Como dito anteriormente pelo @Totor, com o NPTL, que é a implementação atual com o kernel> 2.6, todos os threads têm o mesmo pid, mas eles têm um tid distinto. Você mostra todos os threads de um processo da seguinte maneira:Estes são os nomes dos diretórios sob
/proc/<pid>/task
, e mesmo que renice (1) diga que seu argumento padrão é um pid, quando aplicado a um pid, renomeie apenas o thread principal (este é um bug na implementação do linux, conforme escrito em setpriority (2) ) ), também pode ser aplicado a uma maré e renova o encadeamento. É por isso que a resposta de @Anton é válida.Mas na maioria das vezes existe uma maneira mais fácil de alcançar o resultado desejado, todos esses threads compartilham o mesmo pgid que é o pid do líder do grupo; você pode renice pelo pgid emitindo:
Se você não deseja renomear algum outro processo que dependa do mesmo líder de grupo, use a receita do @ Anton:
ou:
Você também pode querer saber quais são os outros processos do mesmo grupo que não o processo que deseja renice, ou seja, os processos que compartilham têm o mesmo pgid. Você pode usar o ps (1) ,
ps
não permite selecionar processos pelo líder do grupo, mas podeps
fazer um grep a para fazê-lo. Os processos com pgid1908
serão dados pelo comando:ou se você preferir awk a sed:
fonte
$ 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;}'
Enquanto o método de Totor funciona / ainda funciona:$ /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 ...
eu confirmei com / proc, htop, pstree, etc. que eu tenho o top correto PID de nível. Talvez algo tenha mudado no ano passado./proc/8524/task
masrenice -g
falha. Quando você olha para uma árvore de processo, um ramo está no mesmo grupo de processos, não apenas um processo encadeado. Tente novamente verificar o resultado deps -Ljf
.Gostaria de recomendar o uso do argumento -g (grupos de processos) em vez de -p (IDs do processo) enquanto estiver usando o renice. Faz a mesma coisa sem o bash-foo.
ie
fonte
Aqui está um script meu:
fonte