编写含多进程生成目标的Makefile的推荐方法
编写支持多进程生成的Makefile方案推荐
嘿,针对你这个多进程Makefile的需求,结合4核系统和混合IO/CPU密集型任务的场景,我给你几个实用的方案,都是在实际项目里验证过的:
方案一:自定义进程控制+Make并行调度
这个方案适合你对每个任务的进程数有明确要求的场景,核心思路是在每个Recipe内部控制进程数量,同时用Make的并行参数-j来调度不同的run目标,避免总进程数超出系统核心承载。
示例Makefile:
# 自动获取系统核心数,也可以硬编码为4 CORES := $(shell nproc) # 设置Make的并行度为核心数,避免同时启动过多顶级目标 MAKEFLAGS += -j$(CORES) all: run1 run2 run3 # run1:1个进程(适合CPU密集型,独占1核) run1: @echo "启动run1(1个进程)" # 替换为你的实际脚本,确保脚本只启动1个进程 ./run1_script.sh # run2:2个进程(适合IO密集型,IO等待时可以让出CPU) run2: @echo "启动run2(2个进程)" # 后台启动两个任务,用wait等待全部完成 ./run2_task1.sh & ./run2_task2.sh & wait # run3:3个进程(混合CPU/IO,控制CPU密集任务不超核数) run3: @echo "启动run3(最多2个CPU密集+1个IO密集进程)" # CPU密集任务后台启动,最多2个(占满剩余核心) ./run3_cpu_task1.sh & ./run3_cpu_task2.sh & # 延迟启动IO密集任务,避免瞬间占满资源 sleep 3 && ./run3_io_task.sh & wait
方案二:任务分组+依赖控制
如果担心run1/run2/run3同时启动导致总进程数爆炸(比如run2的2个+run3的3个=5个进程,超过4核),可以通过目标分组+依赖来控制执行顺序,让资源占用更合理。
示例Makefile:
CORES := $(shell nproc) # 先执行低资源占用的batch1(run1+run2总3进程),再执行run3 all: batch1 run3 batch1: run1 run2 MAKEFLAGS += -j$(CORES) run1: ./run1_script.sh run2: ./run2_task1.sh & ./run2_task2.sh & wait run3: # run3只启动2个CPU密集进程+1个IO进程,适配剩余资源 parallel -j2 ./run3_cpu_task{} ::: 1 2 & ./run3_io_task.sh & wait
方案三:用GNU Parallel优化资源分配
如果你觉得手动控制进程数太麻烦,推荐用GNU Parallel工具,它能自动根据系统负载调整并行度,尤其适合混合IO/CPU任务的场景,还能简化Recipe的写法。
示例Makefile:
CORES := $(shell nproc) all: run1 run2 run3 # run1:固定1个进程 run1: @echo "启动run1" parallel -j1 ./run1_script.sh ::: # run2:固定2个IO密集进程,并行度拉满也没关系 run2: @echo "启动run2" parallel -j2 ./run2_task{} ::: 1 2 # run3:区分CPU和IO任务,CPU任务用2核,IO任务单独跑 run3: @echo "启动run3" # CPU密集任务限制为2核 parallel -j2 ./run3_cpu_task{} ::: 1 2 & # IO密集任务单独执行 parallel -j1 ./run3_io_task.sh ::: wait
关键注意事项
- CPU密集型任务:并行数不要超过系统核心数,避免上下文切换浪费资源;
- IO密集型任务:可以适当增加并行数(比如核心数的1.5-2倍),利用IO等待的空闲CPU;
- 必须加
wait:确保Recipe执行完成后所有子进程都结束,否则Make会提前认为目标完成; - 日志输出:用
@echo添加任务启动提示,方便排查问题; - 自动获取核心数:用
$(shell nproc)代替硬编码,让Makefile更通用。
内容的提问来源于stack exchange,提问作者sine nomine
相关产品推荐
相关产品推荐

