主要观点:本文介绍了 GNU make 的“作业服务器”实现,包括其设计目的、工作原理、需求及一些相关问题和替代方案。
关键信息:
- GNU make 可并行调用多个命令,常见的是“最多 N 个”并行,作业服务器功能针对此类型。
- 递归构建环境下,单个 GNU make 实例无法知道所有实例的作业运行情况,导致并行效率低下。
- 1999 年 2 月 Howard Chu 提出用管道实现作业服务器的基本想法,经过多人讨论和测试最终确定实现方式。
- 作业服务器实现方式需概念简单、绝对可靠、尽可能可移植。
- 具体实现包括用户指定 -j N 选项,创建管道写入 N - 1 个令牌,构建特殊 -j 选项传递给子 make 等。
- 处理作业时需获取令牌,作业完成后写回令牌,非子 make 作业会关闭作业服务器管道。
- 要同时处理信号和文件描述符事件很棘手,通过安装信号处理程序、设置标志等方式解决,但存在一些问题,如并非所有操作系统都正确支持 SA_RESTART 等。
重要细节: - 初始顶级 make 创建管道并写入令牌,子 make 通过特殊 -j 选项访问管道。
- 运行作业时,若实例无作业运行可直接启动,有作业运行则从管道获取令牌,作业完成后写回令牌。
- 信号处理程序用于处理 SIGCHLD 信号,关闭文件描述符等操作,设置 SA_RESTART 标志避免手动处理 EINTR 错误。
- 存在 race condition,通过信号处理程序关闭文件描述符来消除。
- 由于部分操作系统不支持 SA_RESTART,需在 GNU make 中添加特殊代码处理系统调用返回 EINTR 的情况。
- 还考虑过使用线程和内部管道结合 select 的方式,但因单线程、可移植性等问题被拒绝。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。