我有一个 bash 脚本,它对 TSV 文件的每一列应用不同的转换/映射。我正在尝试使用 GNU 并行进行并行化,但是我的代码挂起。
为简单起见,请考虑
cat
、恒等映射器(即输入 -> 输出)和三列的 TSV 文件(使用 paste
和 seq
动态生成)
n=1000000
map=cat # identity: inp -> out
rm -f tmp.col{1,2}.fifo
mkfifo tmp.col{1,2}.fifo
paste <(seq $n) <(seq $n) <(seq $n) \
| tee >(cut -f1 | $map > tmp.col1.fifo) \
| tee >(cut -f2 | $map > tmp.col2.fifo) \
| cut -f3- \
| paste tmp.col{1,2}.fifo - \
| python -m tqdm > /dev/null
上面的代码运行良好。
注意:
打印速度python -m tqdm > /dev/null
但是我们可以使用 GNU 并行的
--pipe --keep-order
参数来并行化映射任务。这是一个有效的最小并行示例:
seq 100 | parallel --pipe -k -j4 -N10 'cat && sleep 1'
现在将它们放在一起,这是我的并行映射列的代码:
n=1000000
map=cat # identity map: inp -> out
rm -f tmp.col{1,2}.fifo
mkfifo tmp.col{1,2}.fifo
paste <(seq $n) <(seq $n) <(seq $n) \
| tee >(cut -f1 | parallel --id jobA --pipe -k -j4 -N1000 "$map" > tmp.col1.fifo) \
| tee >(cut -f2 | parallel --id jobB --pipe -k -j4 -N1000 "$map" > tmp.col2.fifo) \
| cut -f3- \
| paste tmp.col{1,2}.fifo - \
| python -m tqdm > /dev/null
这应该可以工作,但是这段代码冻结了。为什么会冻结以及如何解冻?
环境:x86_64 上的 Linux 5.15.0-116-generic、Ubuntu 22.04.4 LTS
FIFO 有大小限制,你能用这种方式重新组织脚本吗?
#!/bin/bash
n=${1-10}
map=cat
rm -f tmp.col{1,2}.fifo
mkfifo tmp.col{1,2}.fifo
trap "rm -f tmp.col{1,2}.fifo" EXIT
input=/tmp/input
paste <(seq $n) <(seq $((n+1)) $((2*n)) ) <(seq $((2*n+1)) $((3*n))) > $input
paste <(cut -f1 $input | parallel --id jobA --pipe -k -j4 -N1000 "$map")\
<(cut -f2 $input | parallel --id jobA --pipe -k -j4 -N1000 "$map")\
<(cut -f3 $input) \
| python -m tqdm > /dev/null
与
一起奔跑bash test.sh 100