cpulimit em um script bash que executa outros comandos
On Fevereiro 10, 2021 by adminEu tenho um script bash que executa outros comandos com uso intensivo de cpu.
Quando eu aplico cpulimit
no script bash, a saída de top
mostra processos para os comandos dentro do script ainda executados sem limitação por cpulimit
. Gostaria de saber como posso limitar o uso da CPU dos comandos dentro do script bash?
Resposta
De acordo com cpulimit --help
:
-i, --include-children limit also the children processes
Não testei se isso se aplica a filhos de crianças, nem investiguei como isso é implementado.
Como alternativa, você pode usar cgroups
, que é um recurso do kernel.
Os cgroups não fornecem nativamente um meio de limitar os processos filhos também, mas você pode usar o daemon do mecanismo de regras cg (cgred) fornecido por libcgroup; os comandos cgexec
e cgclassify
que vêm do pacote libcgroup fornecem um --sticky
sinalize para fazer com que as regras se apliquem aos processos filho também.
Esteja ciente de que há uma condição de corrida envolvida que poderia (pelo menos teoricamente) resultar em alguns processos filho não sendo restritos corretamente . No entanto, como você está usando atualmente cpulimit
, que é executado no espaço do usuário de qualquer maneira, você já não tem um limite de CPU 100% confiável de modo que esta condição de corrida não deve ser um obstáculo para você.
Eu escrevi bastante sobre o daemon do mecanismo de regras cg em minha auto-resposta aqui:
Resposta
Provavelmente, você não pode “t.
cpulimit
” A lógica é muito simples, leva pid do processo e simplesmente enviar seu sinal kill -STOP $PID
, depois disso kill -CONT $PID
, e novamente, e novamente, e novamente e novamente ……
E medir o uso da CPU para calcular o atraso entre STOP e CONT.
No seu caso, pstree
de script bash complexo levaria N * x telas do console.
Posso sugerir outro método para fazer o downgrade do uso da CPU de qualquer script bash ou mesmo executável binário.
1) nice
– seu processo de captura e aumento ou diminuição de sua prioridade de -20 (Prioridade mais alta) para 20 (Prioridade mais baixa). Provavelmente em diapasão muito baixo, é por isso que aparecem outros dois utils e ganchos de kernel:
2) ionice
– pode ser que seja a segunda geração de nice
. Você pode separar os processos por prioridade de 0 (prioridade mais baixa) a 7 (prioridade mais alta). Além disso, você pode separar os processos por classes, em tempo real (mais alto), best-efforts
(meio), inativo (mais baixo) e nenhum (padrão).
3) chrt
– a coisa mais importante que já conheci, é semelhante a cpulimit
por seu poder e domínio no processo. Aqui, você também pode encontrar classes de prioridade, idle
, real-time
, fifo
, batch
, etc … E diapasão de prioridades muito grande, de 1 a 99.
Por exemplo, você poderia iniciar um grande processo com chrt -r -p 99 process
– e consumirá todos os seus recursos.
Da mesma forma, qualquer daemon enorme poderia funcionar em “segundo plano” com chrt -r -p 0 process
– ele esperará por todos os outros enquanto os recursos de um sistema estiverem ocupados.
De qualquer forma, sugiro que você leia man chrt
e man ionice
antes de começar.
Por exemplo, estou usando rtorrent
para p2p. É a tarefa de prioridade mais baixa para o meu sistema, então estou lançando-a da seguinte maneira:
nice -n 20 chrt -i 0 ionice -c3 /usr/bin/rtorrent
Ou você pode pegar os ganchos & haks caminho. E escreva seu próprio script cpulimit_wrapper. Por exemplo:
# cat bash_script.sh #!/bin/bash while sleep 0; do find / dd if=/dev/random of=/tmp/random.bin bs=1M count=1000 done
plus
# cat cpulimit.sh #!/bin/bash TARGET=$1 [ -z "$TARGET" ] && echo "Usage bash cpulimit.sh command" && exit 1 cpulimit -l 1 bash $TARGET while sleep 0;do lsof -n -t $TARGET | xargs pstree -p | sed -e "s/(/(\n/g" | sed -e "s/)/\n)/g" | egrep -v "\(|\)" | while read i; do echo $i; cpulimit -l 1 -b -p $i; done done
Resposta
Agora, a melhor maneira para mim era executar um script que permitisse cpulimit processos de controle em segundo plano de Askubuntu :
#!/bin/bash #The first variable is to set the number of cores in your processor. The reason that the number of cores is important is that you need to take it into consideration when setting cpulimit"s -l option. This is explained on the cpulimit project page (see http://cpulimit.sourceforge.net/): "If your machine has one processor you can limit the percentage from 0% to 100%, which means that if you set for example 50%, your process cannot use more than 500 ms of cpu time for each second. But if your machine has four processors, percentage may vary from 0% to 400%, so setting the limit to 200% means to use no more than half of the available power." NUM_CPU_CORES=$(nproc --all) #Automatically detects your system"s number of CPU cores. cpulimit -e "ffmpeg" -l $((50 * $NUM_CPU_CORES))& #Limit "ffmpeg" process to 50% CPU usage. cpulimit -e "zero-k" -l $((50 * $NUM_CPU_CORES))& #Limit "zero-k" process to 50% CPU usage. cpulimit -e "mlnet" -l $((50 * $NUM_CPU_CORES))& #Limit "mlnet" process to 50% CPU usage. cpulimit -e "transmission-gtk" -l $((50 * $NUM_CPU_CORES))& #Limit "transmission-gtk" process to 50% CPU usage. cpulimit -e "chrome" -l $((40 * $NUM_CPU_CORES))& #Limit "chrome" process to 40% CPU usage.
Editar para quais processos são usado em seu script e deixá-lo ser executado. cpulimit será executado em segundo plano e observará os processos solicitados e limita seu uso. Se algum dos processos for concluído, cpulimit ainda permanecerá e limitar os processos se eles voltarem a funcionar.
(Eu encontrei um problema estranho quando tentei executar o ffmpeg através de um for-loop no terminal. Paradoxalmente, isso gerou duas instâncias do ffmpeg que tornaram cpulimit “ing quase u seless. Não consegui encontrar uma resposta para o problema. Portanto, mesmo que seja apenas um loop for, talvez você precise escrever um script para esta.)
Resposta
Use o parâmetro -P
e coloque o caminho absoluto antes do executável.
Resposta
Tentei configurar o alias para cpulimit -l 50 ffmpeg
em .bashrc
alias ffmpegl = "cpulimit -l 50 ffmpeg"
e depois usei em meu script com o seguinte código para aliases de origem
shopt -s expand_aliases source /home/your_user/.bashrc
Agora posso usar cpulimit com ffmpeg em qualquer lugar dentro do script para vários comandos usando o alias. Testado em Linux 6.5.Funciona perfeitamente.
Comentários
- infelizmente, o comando cpulimit entra em segundo plano, tornando impossível o script iterativo
- Eu também encontrei isso; como uma solução alternativa se as iterações não forem muito complexas, usando uma combinação de ‘ find ‘ canalizado para ‘ xargs ‘ fez o trabalho para mim.
Deixe uma resposta