Você pode criar um pool de processos com scripts de shell?

2

Digamos que eu tenha um grande número de trabalhos (dezenas ou centenas) que precisam ser executados, mas eles exigem muita CPU e apenas alguns podem ser executados de uma só vez. Existe uma maneira fácil de executar X jobs de uma vez e iniciar um novo quando terminar? A única coisa que eu posso fazer é algo como abaixo (pseudo-código):

jobs=(...);
MAX_JOBS=4;
cur_jobs=0;
pids=(); # hash/associative array
while (jobs); do
    while (cur_jobs < MAX_JOBS); do
        pop and spawn job and store PID and anything else needed;
        cur_jobs++;
    done
    sleep 5;
    for each PID:
        if no longer active; then
            remove PID;
            cur_jobs--;
done

Eu sinto que estou complicando demais a solução, como sempre faço. O sistema de destino é o FreeBSD, se houver alguma porta que faça todo o trabalho pesado, mas uma solução genérica ou idioma comum seria preferível.

    
por Jason Lefler 29.01.2015 / 07:23

3 respostas

6

Se você tem o GNU Parallel, você pode fazer isso:

parallel do_it {} --option foo < argumentlist

O GNU Parallel é um paralelizador geral e facilita a execução de trabalhos em paralelo na mesma máquina ou em várias máquinas para as quais você tem acesso ssh.

Se você tem 32 tarefas diferentes que você quer rodar em 4 CPUs, uma forma direta de paralelizar é rodar 8 tarefas em cada processador:

O

GNUParallelgeraumnovoprocessoquandoumtermina-mantendoasCPUsativaseeconomizandotempo:

Instalação

Se o GNU Parallel não for empacotado para sua distribuição, você poderá fazer uma instalação pessoal, que não requer acesso root. Isso pode ser feito em 10 segundos ao fazer isso:

(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash

Para outras opções de instalação, consulte o link

Saiba mais

Veja mais exemplos: link

Assista aos vídeos de introdução: link

Percorra o tutorial: link

Inscreva-se na lista de e-mail para obter suporte: link

    
por 29.01.2015 / 09:28
0

Você pode, mas é complicado e frágil. Existem várias opções, uma delas é xargs .

Os problemas encontrados quando se confia no controle de tarefas e nos sinais são discutidos neste interessante artigo, uma leitura realmente recomendada:

link

O cara aparentemente criou uma nova ferramenta prll que pode executar funções de shell arbitrárias em paralelo (com tamanho de pool detectado automaticamente ou definido pelo usuário), que usa um processo de controle que sincroniza todas as entradas e saídas. / p>

Confira aqui: link

    
por 29.01.2015 / 09:12
0

Eu tive exatamente a mesma situação que você, mas as tarefas que preciso executar em paralelo são comandos que executam scripts do Ruby. Primeiro eu preciso admitir que não é perfeito, em vez disso, é frágil.

O que eu fiz no meu código de ruby foi

counting_process = IO.popen "ps -e | grep 'YourCMDPattern' -c"
count_of_processes = counting_process.readlines[0].to_i

Então, em um loop while, estou checando a contagem de processos periodicamente, então aciono o comando shell para executar um certo número de novos processos com o IO.popen do ruby quando a contagem está abaixo do número da execução paralela que quero manter .

Note que o comando shell que eu preciso executar é dinâmico e contém uma variável gerada a partir do código ruby, por isso eu tenho que fazê-lo no script ruby.

O GNU Parallel parece ser uma opção melhor para você se o ruby não estiver envolvido.

    
por 06.03.2015 / 19:42