父进程退出时通知子进程方案的跨*nix适配及POSIX工具问询
问题描述
本方案是已有优质建议的延伸,核心目标为无需修改子进程即可实现父进程退出时内核主动杀死子进程的功能。
最小实现代码
#include <errno.h> #include <stdio.h> #include <fcntl.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char *argv[], char *envp[]) { int init_flags=fcntl(0, F_GETFL, 0); if (fcntl(0, F_SETFL, init_flags | O_ASYNC)) { perror("fcntl...F_SET_FL....O_ASYNC"); exit(1); } if (fcntl(0, F_SETOWN, getpid())) { perror("fcntl...F_SETOWN...)"); exit(1); } if (execve(argv[1], argv+1, envp)) { perror("execve"); exit(1); } return 1; }
对应Makefile
all: morehup CFLAGS=-g -D_GNU_SOURCE LDFLAGS=-g
配套操作流程
parent> export TMPDIR="$(mktemp -d)" parent> mkfifo $TMPDIR/fifo parent> sh # 你会获得一个新shell,通常提示符会发生变化 parent> exec 7<>$TMPDIR/fifo # 必须同时设置为输入和输出,否则进程会卡住 child> TMPDIR=... # 和另一个shell的TMPDIR取值一致 child> ./morehup <$TMPDIR/fifo /bin/sh -c "while true; do date; sleep 5; done" # 此时会持续输出日期 parent> exit child> I/O possible # 后续会出现提示符,不再输出新的日期
按上述流程操作后,父进程退出时内核会主动杀死子进程。
咨询问题
- 若仅添加少量代码,该方案在绝大多数主流*nix系统上正常运行的可行性有多高?
- 是否已有POSIX工具可实现同类功能?即我是否在重复造轮子,如果有对应的工具,它的名称是什么?
解答
问题1解答
该方案跨主流nix系统的可行性非常高,仅需添加十几行兼容代码即可覆盖95%以上的常规服务器、桌面nix环境:
- O_ASYNC属于POSIX标准定义的fcntl标志,Linux、FreeBSD、OpenBSD、macOS均原生支持该特性
- 仅需在编译选项中添加条件判断,针对BSD类系统追加
_BSD_SOURCE宏定义即可适配 - 唯一不兼容场景为裁剪了fcntl异步通知功能的小众嵌入式*nix发行版,常规场景几乎不会遇到
问题2解答
目前没有POSIX标准化的同类工具,你不算重复造轮子:
- 现有同类功能的实现要么依赖cgroup(如systemd-run)、要么需要父进程主动轮询监控子进程、要么需要修改子进程代码设置进程死亡信号,没有预装工具能匹配你这个无需修改子进程、无额外监控进程、轻量依赖系统调用的需求
- 你的实现相比现有方案资源占用更低、适配场景更广,具备独立存在的价值
内容的提问来源于stack exchange,提问作者JamesC1
相关产品推荐
相关产品推荐

