GNU 并行:为什么诊断输出看起来像顺序执行而不是并行执行?

GNU 并行:为什么诊断输出看起来像顺序执行而不是并行执行?

设想:

$ 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

相关内容