Você está sendo atingido por dois problemas.
Isso
(seq 200; sleep 20) | parallel -j10 -k echo
impressões:
1
2
e depois pára até que o sleep 20
seja concluído.
Uma correção parcial parece ser mover start_more_jobs()
fora do loop while
:
--- a/src/parallel
+++ b/src/parallel
@@ -4062,9 +4062,8 @@ sub reaper {
# $stiff = pid of dead process
if(wantarray) {
push(@pids_reaped,$stiff);
- } else {
- $children_reaped++;
}
+ $children_reaped++;
if($Global::sshmaster{$stiff}) {
# This is one of the ssh -M: ignore
next;
@@ -4112,12 +4111,12 @@ sub reaper {
}
}
$job->cleanup();
- start_more_jobs();
if($opt::progress) {
my %progress = progress();
::status_no_nl("\r",$progress{'status'});
}
}
+ if($children_reaped) { start_more_jobs(); }
$opt::sqlmaster and $Global::sql->run("COMMIT;");
debug("run", "done ");
return wantarray ? @pids_reaped : $children_reaped;
Isso pode custar algum desempenho se você tiver muitos trabalhos de curta duração. Eu não medi o quanto.
A outra parte do problema é devido a uma decisão de projeto no GNU Parallel.
Argumentos no GNU Parallel são lidos usando o operador de diamante (< >). Isto lê uma linha completa antes de continuar. A leitura de (sleep 20)
gera apenas um fim de arquivo após sleep
terminar e, assim, bloqueia até sleep
terminar.
Então, quando o GNU Parallel lê o byte final, ele tem que esperar que o sleep
termine de descobrir que esse é realmente o fim do arquivo.
Não vejo uma maneira fácil de alterar essa parte do design.
Felizmente, isso não impede que os trabalhos sejam executados, como você pode ver se você executar date
. As tarefas são iniciadas imediatamente, é apenas a saída que está aguardando o sleep
:
(seq 20; sleep 5) | parallel -j10 -k 'date;echo'
Em outras palavras: Seu problema não está relacionado a -N2
. Você não pode ver o problema aqui:
(printf '%s(printf '%s(printf '%s(printf '%s(seq 200; sleep 20) | parallel -j10 -k echo
' {1..40}; sleep 2) | parallel -j4 --null -k --lb -N 2 'date;'echo {1} {2}
' {1..40}; sleep 2) | parallel -j8 --null -k --lb -N 2 echo {1} {2}
' {1..40}; sleep 2) | parallel -j4 --null -k --lb -N 2 echo {1} {2}
' {1..4}; sleep 2) | parallel --null -k --lb -N 2 echo {1} {2}
Mas você pode ver o problema aqui. Isso pausa antes dos últimos 4-8 elementos:
1
2
Esta pausa antes dos últimos 8-10 elementos:
--- a/src/parallel
+++ b/src/parallel
@@ -4062,9 +4062,8 @@ sub reaper {
# $stiff = pid of dead process
if(wantarray) {
push(@pids_reaped,$stiff);
- } else {
- $children_reaped++;
}
+ $children_reaped++;
if($Global::sshmaster{$stiff}) {
# This is one of the ssh -M: ignore
next;
@@ -4112,12 +4111,12 @@ sub reaper {
}
}
$job->cleanup();
- start_more_jobs();
if($opt::progress) {
my %progress = progress();
::status_no_nl("\r",$progress{'status'});
}
}
+ if($children_reaped) { start_more_jobs(); }
$opt::sqlmaster and $Global::sql->run("COMMIT;");
debug("run", "done ");
return wantarray ? @pids_reaped : $children_reaped;
Ao executar date
, você pode ver que o problema não é o início dos trabalhos - está apenas adiando a impressão:
(seq 20; sleep 5) | parallel -j10 -k 'date;echo'