我试图让一个“父目标”等待“平行子目标”完成,然后再对“父目标”的“身体”进行某些操作。
在下面的示例中,仅在所有目标@echo "Print this only after *ALL* the previous PARALLEL tasks are done!"
,foo-task1
和foo-task2
完成之后 打印消息foo-task3
。< / p>
如果我在那些“儿童目标”的末尾删除与号(&
),则它们会变成串行,但这不是预期的行为。它们的行为应类似于“线程池”或“进程池”。我不预先知道哪个目标将最后完成,因此无法从瓶颈目标中删除“&”号(&
)。
这些目标表示对远程REST API的HTTP调用,这可能需要花费不同的时间才能完成。我想等待这些“并行REST调用”查看它们是否成功,然后再在foo-parallel
中打印最终消息。
这些“并行目标”将返回stdout / stderr,因此我希望父目标可以等待它们并在出现某些错误时失败。
我该怎么办?
foo-task1:
@bash -c 'sleep 1 && echo "task1" &'
foo-task2:
@bash -c 'sleep 1 && echo "task2" &'
foo-task3:
@bash -c 'sleep 2 && echo "task3" &'
foo-parallel: foo-task3 foo-task2 foo-task1
@echo "Print this only after *ALL* the previous PARALLEL tasks are done!"
命令make
版本:
$ make --version
GNU Make 4.1
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
编辑:
此目标定义稍有不同(我更改了sleep
次,只是为了确保消息按延迟顺序打印,而不是按代码顺序打印):
foo-parallel:
@bash -c 'sleep 5 && echo "task1" & \
sleep 1 && echo "task2" & \
sleep 2 && echo "task3" & \
wait; \
echo "done here!"'
打印:
$ make foo-parallel
task2
task3
task1
done here!
但是我需要将所有task1
,task2
和task3
的逻辑放在同一个目标中。我想将这些任务划分为不同的目标。
答案 0 :(得分:1)
我认为您想使用-j
选项:
foo-task1:
@sleep 1
@echo "task1"
foo-task2:
@sleep 1
@echo "task2"
foo-task3:
@sleep 2
@echo "task3"
foo-parallel: foo-task3 foo-task2 foo-task1
@echo "Print this only after *ALL* the previous PARALLEL tasks are done!"
并运行make -j3 foo-parallel
-make
将以正确的依赖关系并行运行。查看更多Parallel Execution部分:
GNU make知道如何一次执行多个配方。通常, 一次只能执行一个配方,等待完成 在执行下一个之前。但是,“-j”或“ --jobs”选项说明 同时执行许多配方。
答案 1 :(得分:1)
如果不使用make的-j
选项,则无法执行此操作。默认情况下,make构建一个目标,等待其完成,然后构建下一个目标。只有-j
才能支持同时运行的多个目标。
foo-parallel: foo-task3 foo-task2 foo-task1
@echo "Print this only after *ALL* the previous PARALLEL tasks are done!"
foo-task1:
@sleep 1 && echo "task1"
foo-task2:
@sleep 1 && echo "task2"
foo-task3:
@sleep 2 && echo "task3"
然后运行:make -j
,或者如果您想限制并行构建的数量,请使用make -j2
或任意多个。
如果您真的想避免键入-j
,则可以使用递归make:
foo-parallel:
@$(MAKE) -j foo-task1 foo-task2 foo-task3
@echo "Print this only after *ALL* the previous PARALLEL tasks are done!"
foo-task1:
@sleep 1 && echo "task1"
foo-task2:
@sleep 1 && echo "task2"
foo-task3:
@sleep 2 && echo "task3"
但是,如果有人调用make -j
,这可能会引起奇怪的警告。通常,我认为最好由调用make
的人来决定他们想要针对特定系统的并行度。