【问题标题】:Bash complex pipeline dependenciesBash 复杂的管道依赖项
【发布时间】:2018-02-16 21:08:43
【问题描述】:

我正在尝试在单个 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

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

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

如果这适用于 OSX 和 Linux,那就太好了。我希望 Bash 专家能够加入并展示一种在 Bash 中表达这一点的简洁方式。

【问题讨论】:

标签: linux bash concurrency parallel-processing pipeline


【解决方案1】:

正如问题的 cmets 所指出的,以下 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、... 的文件碰巧存在。

【讨论】:

  • 我不会想到使用 Make 来编排任务,这是个好主意,我必须记住它:)
【解决方案2】:

使这项工作适用于 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-02
    • 1970-01-01
    • 1970-01-01
    • 2012-03-26
    • 2012-09-20
    • 2020-06-11
    相关资源
    最近更新 更多