![GNU Parallel 在程序退出之前不会运行作业](https://linux22.com/image/142237/GNU%20Parallel%20%E5%9C%A8%E7%A8%8B%E5%BA%8F%E9%80%80%E5%87%BA%E4%B9%8B%E5%89%8D%E4%B8%8D%E4%BC%9A%E8%BF%90%E8%A1%8C%E4%BD%9C%E4%B8%9A.png)
当我运行时(rss-notifier 的代码包含在末尾),
rss-notifier.zsh https://www.wuxiaworld.com/feed/chapters ".*"|parallel --null -k --lb echo {}
我明白了,
Title: Sovereign of the Three Realms -
答案1
您受到两个问题的困扰。
这
(seq 200; sleep 20) | parallel -j10 -k echo
印刷:
1
2
然后停止直到sleep 20
完成。
部分修复似乎是移到循环start_more_jobs()
之外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;
如果您有许多短期作业,这可能会降低一些性能。我没有测量过多少。
问题的另一部分是由于 GNU Parallel 中的设计决策造成的。
GNU Parallel 中的参数是使用菱形运算符 (<>) 读取的。这会在继续之前读取整行。读取(sleep 20)
仅在完成后生成文件结尾sleep
,因此会阻塞直到sleep
完成。
因此,当 GNU Parallel 读取最后一个字节时,它必须等待sleep
完成才能发现这确实是文件结尾。
我认为没有简单的方法可以改变这部分设计。
幸运的是,这不会阻止作业运行,正如您运行时可以看到的那样date
。作业立即启动,只是等待输出sleep
:
(seq 20; sleep 5) | parallel -j10 -k 'date;echo'
换句话说:您的问题与-N2
.你在这里看不到问题:
(printf '%s\0' {1..4}; sleep 2) | parallel --null -k --lb -N 2 echo {1} {2}
但是你能看到问题在这里。这会在最后 4-8 个元素之前暂停:
(printf '%s\0' {1..40}; sleep 2) | parallel -j4 --null -k --lb -N 2 echo {1} {2}
这会在最后 8-10 个元素之前暂停:
(printf '%s\0' {1..40}; sleep 2) | parallel -j8 --null -k --lb -N 2 echo {1} {2}
通过运行date
您可以看到问题不是作业的启动 - 它只是推迟打印:
(printf '%s\0' {1..40}; sleep 2) | parallel -j4 --null -k --lb -N 2 'date;'echo {1} {2}