我正在尝试在单个Bash脚本中建模构建并发管道。我知道我可以使用其他工具,但此时我是在理解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中表达一种简洁的方式来表达这一点。
答案 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:
目标确保即使名为a1
,a2
,......的文件恰好存在,也会执行所有任务。
答案 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