Bash复杂的管道依赖

时间:2018-02-16 21:08:43

标签: linux bash concurrency parallel-processing pipeline

我正在尝试在单个Bash脚本中建模构建并发管道。我知道我可以使用其他工具,但此时我是在理解Bash的基础上完成的。 Here's a diagram of the task flow that I'm trying to model in Bash.

并行调度作业很容易,最后等待它们很容易。但我希望在任务A.1& A之后立即通过触发任务A.2使其运行得更快。任务X.为了使自己更加努力,任务A.1&任务A.2是相关的&顺序,所以如果我能保持代码顺序也会很好。

#!/usr/bin/bash

{
    echo "Task X"
} &
DEPENDENCY=$!

{
    echo "Task A.1"
    wait "${DEPENDENCY}"
    echo "Task A.2"
} &

{
    echo "Task B.1"
    wait "${DEPENDENCY}"
    echo "Task B.2"
} &

wait

理想情况下,这是我想要的,但它不起作用,因为子进程不能等待彼此 - 这是有道理的 - 但我希望我能以跨平台的方式完成这项工作。 / p>

我实际上有这个工作,但我无法保留部分代码* .1和* .2

如果这可以用于OSX& Linux操作系统。我希望Bash专家可以在Bash中表达一种简洁的方式来表达这一点。

2 个答案:

答案 0 :(得分:4)

正如对问题的评论所指出的,以下Makefile等同于您的shell脚本(但不触及文件系统)

.PHONY: a1 a2 b1 b2 x

all: a2 b2 

a1:
    @echo "Task A.1"

b1:
    @echo "Task B.1"

x:
    @sleep 1.5; echo "Task X"

a2: a1 x
    @echo "Task A.2"

b2: b1 x
    @echo "Task B.2"

尝试使用make -j5以允许五个并行线程。它需要GNU make,它可用于现有的每个平台,即使它可能不是默认分发的。初始.PHONY:目标确保即使名为a1a2,......的文件恰好存在,也会执行所有任务。

答案 1 :(得分:0)

使这项工作适用于OSX& Linux将使用namedpipes向可以继续的批处理作业发出信号。不幸的是,它需要拆分“Task * .1”& “任务* .2”,但这是我现在能想到的最好的。

#!/bin/bash

function cleanup {
  rm -f .task.a.1.done .task.b.1.done
}
trap cleanup EXIT
cleanup

mkfifo .task.a.1.done
mkfifo .task.b.1.done

{
    echo "Task A.1"
    echo -n "" > .task.a.1.done
} &

{
    echo "Task B.1"
    echo -n "" > .task.b.1.done
} &

{
    echo "Task X"
}

{
    cat < .task.a.1.done
    echo "Task A.2"
} &

{
    cat < .task.b.1.done
    echo "Task B.2"
} &

wait