设想:
$ cat libs.txt
lib.a
lib1.a
$ cat t1a.sh
f1()
{
local lib=$1
stdbuf -o0 printf "job for $lib started\n"
sleep 2
stdbuf -o0 printf "job for $lib done\n"
}
export -f f1
cat libs.txt | SHELL=$(type -p bash) parallel --jobs 2 f1
调用及输出:
$ time bash t1a.sh
job for lib.a started
job for lib.a done
job for lib1.a started
job for lib1.a done
real 0m2.129s
user 0m0.117s
sys 0m0.033s
这里我们看到 的执行f1
确实是并行的 ( real 0m2.129s
)。
但是,诊断输出看起来执行是连续的。
我期望得到以下诊断输出:
job for lib.a started
job for lib1.a started
job for lib.a done
job for lib1.a done
为什么诊断输出看起来像顺序执行而不是并行执行?
如何修复诊断输出,使其看起来像并行执行?
答案1
从手册页GNUparallel
:
--group
团体输出。
每个作业的输出都分组在一起,并且仅在命令完成时才打印。首先是 Stdout(标准输出),然后是 stderr(标准错误)。
每个作业大约需要 0.5 毫秒的 CPU 时间,并且取决于较大输出的磁盘速度。
--group
是默认值。也可以看看:
--line-buffer
--ungroup
--tag
[...]
--line-buffer
--lb
基于行的缓冲输出。
--group
将在整个工作中将输出保持在一起。--ungroup
允许输出混合来自一项作业的半行和来自另一项作业的半行。--line-buffer
介于两者之间:GNU parallel 将打印整行,但会允许混合不同作业的生产线。
因此,您应该将--line-buffer
或添加--ungroup
到您的parallel
命令中(根据您的首选行为):
$ grep parallel t1a.sh
cat libs.txt | SHELL=$(type -p bash) parallel --line-buffer --jobs 2 f1
$ bash t1a.sh
job for lib.a started
job for lib1.a started
job for lib.a done
job for lib1.a done