cpulimit en un script bash que ejecuta otros comandos
On febrero 10, 2021 by adminTengo un script bash que ejecuta otros comandos de CPU intensiva.
Cuando solicito cpulimit
en el script bash, la salida de top
muestra los procesos para los comandos dentro del script que aún se ejecutan sin limitación por cpulimit
. Me pregunto cómo puedo limitar el uso de la CPU de los comandos dentro del script bash.
Respuesta
De acuerdo con cpulimit --help
:
-i, --include-children limit also the children processes
No he probado si esto se aplica a los hijos de los niños, ni he investigado cómo se implementa.
Alternativamente, puede usar cgroups
, que es una característica del kernel.
Cgroups no proporciona de forma nativa un medio para limitar los procesos secundarios también, pero puede usar el demonio del motor de reglas cg (cgred) proporcionado por libcgroup; los comandos cgexec
y cgclassify
que provienen del paquete libcgroup proporcionan un --sticky
para hacer que las reglas también se apliquen a los procesos secundarios.
Tenga en cuenta que hay una condición de carrera involucrada que podría (al menos en teoría) dar como resultado que algunos procesos secundarios no se restrinjan correctamente . Sin embargo, como actualmente estás usando cpulimit
que se ejecuta en el espacio de usuario de todos modos, ya no tienes un límite de CPU 100% confiable. por lo que esta condición de carrera no debería ser un factor decisivo para usted.
Escribí bastante extensamente sobre el demonio del motor de reglas cg en mi auto-respuesta aquí:
Respuesta
Probablemente, no pueda «t.
cpulimit
» La lógica es bastante simple, toma el pid del proceso y simplemente envía su señal kill -STOP $PID
, luego kill -CONT $PID
, y nuevamente, y nuevamente, y nuevamente, y nuevamente ……
Y midiendo el uso de la CPU para calcular el retraso entre STOP y CONT.
En su caso, pstree
de un script bash complejo tomaría N * x pantallas de consola.
Puedo sugerirle otro método para degradar el uso de CPU de cualquier script bash o incluso ejecutable binario.
1) nice
– está tomando el proceso y aumentando o disminuyendo su prioridad de -20 (prioridad más alta) a 20 (prioridad más baja). Probablemente en diapasón demasiado bajo, es por eso que aparecen otras dos utilidades y ganchos del kernel:
2) ionice
– puede ser que sea la segunda generación de nice
. Puede separar los procesos por prioridad de 0 (prioridad más baja) a 7 (prioridad más alta). Además, puede separar los procesos por clases, en tiempo real (más alto), best-efforts
(medio), inactivo (más bajo) y ninguno (predeterminado).
3) chrt
– lo más alto que he conocido, es similar a cpulimit
por su poder y dominio sobre el proceso. Aquí también podría conocer las clases de prioridad, idle
, real-time
, fifo
, batch
, etc … Y diapasón de prioridades muy grande, de 1 a 99.
Por ejemplo, podría lanzar un proceso enorme con chrt -r -p 99 process
– y devorará todos sus recursos.
De la misma manera, cualquier daemon enorme podría funcionar en «segundo plano» con chrt -r -p 0 process
– esperará a todos los demás mientras los recursos de un sistema estén ocupados.
De todos modos, le sugiero que lea man chrt
y man ionice
antes de comenzar.
Por ejemplo, «estoy usando rtorrent
para p2p. Es la tarea de menor prioridad para mi sistema, luego la estoy lanzando de tal manera:
nice -n 20 chrt -i 0 ionice -c3 /usr/bin/rtorrent
O, puede tomar los ganchos & haks way. Y escribe tu propio script cpulimit_wrapper. Por ejemplo:
# 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
Respuesta
Ahora, la mejor manera para mí era ejecutar un script que permitiera cpulimit controlar procesos en segundo plano desde 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.
Edite a qué procesos son utilizado en su secuencia de comandos y dejar que se ejecute. cpulimit se ejecutará en segundo plano y observará los procesos solicitados y limitará su uso. Si alguno de los procesos está terminado, cpulimit permanecerá y limitar los procesos si alguna vez vuelven a cobrar vida.
(Encontré un problema extraño cuando intenté ejecutar ffmpeg a través de un bucle for en la terminal. Paradójicamente, esto generó dos instancias de ffmpeg que hicieron que cpulimit «casi u sin serenidad. No pude encontrar una respuesta a cuál es el problema. Por lo tanto, incluso si «es» sólo un bucle for «, es posible que deba escribir un script para esta.)
Respuesta
Utilice el parámetro -P
y coloque la ruta absoluta antes de ejecutable.
Respuesta
Intenté configurar un alias para cpulimit -l 50 ffmpeg
en .bashrc
alias ffmpegl = "cpulimit -l 50 ffmpeg"
y luego lo usé en mi script con el siguiente código para generar alias
shopt -s expand_aliases source /home/your_user/.bashrc
Ahora puedo usar cpulimit con ffmpeg en cualquier lugar dentro del script para múltiples comandos usando el alias. Probado en Scientific Linux 6.5. Funciona a la perfección.
Comentarios
- desafortunadamente, el comando cpulimit pasa a segundo plano, lo que hace imposible la escritura iterativa
- También encontré esto; como solución alternativa si las iteraciones no son muy complejas, utilice una combinación de ‘ find ‘ canalizado a ‘ xargs ‘ hizo el trabajo por mí.
Deja una respuesta