Bash复杂的管道依赖性

mun*_*nro 3 linux parallel-processing bash concurrency pipeline

我正在尝试在单个Bash脚本中对构建并发管道进行建模。我知道我可以使用其他工具,但是出于理解Bash的目的,我正在这样做。 这是我要在Bash中建模的任务流图。

并行调度作业很容易,而在最后等待所有作业很容易。但是我想通过在任务A.1和任务X之后立即触发任务A.2来使其运行更快。为了使自己更难对付,任务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
Run Code Online (Sandbox Code Playgroud)

理想情况下,这是我想要的,但是它不起作用,因为子进程不能互相等待-这很有意义-但我希望我可以跨平台的方式完成这项工作。

我实际上已经在工作,但是我无法保留* .1和* .2部分的代码

如果这可以在OSX和Linux上运行,那也很好。我希望Bash专家能够参与进来,并展示一种简洁的方式来用Bash表达这一点。

Dar*_*rio 5

正如对该问题的注释所指出的那样,以下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"
Run Code Online (Sandbox Code Playgroud)

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


mun*_*nro 1

在 OSX 和 Linux 上实现此功能的一种方法是使用命名管道向批处理作业发出信号,表明它们可以继续。不幸的是,它需要拆分“任务 *.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
Run Code Online (Sandbox Code Playgroud)