Encontre com `-exec` mas com atraso

Encontre com `-exec` mas com atraso

Eu tenho este código para otimizar o tamanho da imagem de todas as minhas imagens dentro /dirdo diretório:

find /dir/ -iregex ".*\.\(jpg\|jpeg\)" -exec jpegoptim --strip-all {} \;

Quando executo esse código, ele consome muito da CPU do meu servidor. Então estou me perguntando: é possível adicionar um atraso entre cada um exec? Por exemplo, quero 100 milissegundos de atraso entre cada vez que execcada imagem é chamada, dessa forma a CPU não fica muito ocupada.

O que você sugeriria? Meu servidor está executando o Centos 8.

Responder1

Você também pode adicionar mais comandos usando mais -execs

find /dir/ -iregex ".*\.\(jpg\|jpeg\)" -exec jpegoptim --strip-all {} \; -exec sleep 0.1 \;

Mas como regra geral, se você quiser que ele funcione totalmente, mas sendolegalpara outros processos, é muito simples usar o nice:

nice find /dir/ -iregex ".*\.\(jpg\|jpeg\)" -exec jpegoptim --strip-all {} \;

Responder2

Esta é a razão pela qual os comandos gostam nicee ioniceforam criados.

  • nicepode ser usado para reduzir a prioridade da CPU do processo
  • ionicepode ser usado para reduzir a prioridade de IO do processo

Uma combinação deles pode garantir que seu processo ocupe apenas uma pequena fatia do processador disponível e da capacidade de E/S. Este exemplo empurra o processo IO para a extremidade inferior da classe de "melhor esforço":

ionice -c2 -n7 find...

Mude -c2para -c3para garantir que seu processo só será executado quando o subsistema IO estiver ocioso.

Este exemplo reduz a permissão do processador para uma prioridade baixa:

nice -n12 find...

Mude -n12para -n19para obter a menor prioridade possível.

Combine-os para obter o efeito máximo:

ionice -c2 -n7 nice -n12 find...

Responder3

Você pode usar um loop de shell com -execa opção de findexecutar um loop for em execução jpegoptimpara cada arquivo de imagem encontrado, com um atraso adicional

find /dir/ -iregex ".*\.\(jpg\|jpeg\)" -exec sh -c '
  for file; do jpegoptim --strip-all "$file"; sleep 0.1; done' -- {} +

Responder4

Ao usar -exec cmd ... {} ';', você está executando uma instância cmdpara cada arquivo. jpegoptimpode processar mais de um arquivo por chamada, portanto você evitaria muito trabalho de sua CPU alterando-o para -exec cmd ... {} +:

LC_ALL=C nice find . '(' -name '*.[jJ][pP][gG]' -o -name '*.[jJ][pP][eE][gG]' ')' \
  -type f -exec jpegoptim --strip-all {} +

(Aqui com ofind comando convertido para sintaxe padrão e melhorado para que correspondatodosnomes de arquivos que terminam em .jpgou .jpegsem distinção entre maiúsculas e minúsculas e restritos a arquivos normais).

nicediz ao agendador para priorizar outras tarefas em detrimento daquelas que estão em execução findou jpegoptim. É muito mais eficiente do que colocar essas tarefas sleeparbitrariamente, mesmo quando seus processadores têm muito tempo de sobra (considere também que leva algum tempo de CPU para executar, carregar, inicializar, etc. um sleeputilitário).

informação relacionada