我的makefile中的一个目标是一个非常耗时且耗时的任务。但我可以分开工作负载并多次并行运行任务,以加快整个过程。
我的问题是make并没有等待所有进程完成。
考虑这个名为myTask.sh
的简单脚本:
#!/bin/bash
echo "Sleeping $1 seconds"
sleep $1
echo "$1 are over!"
现在,让我们从bash脚本中调用它,并使用wait
等待所有任务完成:
#!/bin/bash
echo "START"
./myTask.sh 5 &
./myTask.sh 15 &
./myTask.sh 10 &
wait # Wait for all tasks to complete
echo "DONE"
输出符合预期:
START
Sleeping 15 seconds
Sleeping 5 seconds
Sleeping 10 seconds
5 are over!
10 are over!
15 are over!
DONE
但是在Makefile
中尝试相同时:
test:
echo "START"
./myTask.sh 5 &
./myTask.sh 15 &
./myTask.sh 10 &
wait
echo "DONE"
它不起作用:
START
Sleeping 5 seconds
Sleeping 15 seconds
Sleeping 10 seconds
DONE
sweber@pc:~/testwait $5 are over!
10 are over!
15 are over!
当然,我可以创建多个目标,这些目标可以是"内置"并行make,或者让make只运行运行任务的bash脚本。 但有没有办法像我已经尝试过的那样做呢?
答案 0 :(得分:10)
为什么不使用make中已经建立的机制?像这样:
task%:
sh task.sh $*
test: task5 task15 task10
echo "DONE"
您将能够在make命令行上调整并行度,而不是将其硬编码到makefile中(例如,如果您有2个可用核心,请使用'make -j 2 test'并'make -j 32测试'如果你有32个核心)
答案 1 :(得分:7)
配方中的每个单独的逻辑行都在其自己的shell中调用。所以你的makefile基本上就是这样运行的:
test:
/bin/sh -c 'echo "START"'
/bin/sh -c './myTask.sh 5 &'
/bin/sh -c './myTask.sh 15 &'
/bin/sh -c './myTask.sh 10 &'
/bin/sh -c 'wait'
/bin/sh -c 'echo "DONE"'
你应该使用分号和反斜杠/换行符在一个shell中运行它以将物理线组合成一个逻辑行:
test:
echo "START"; \
./myTask.sh 5 & \
./myTask.sh 15 & \
./myTask.sh 10 & \
wait; \
echo "DONE"