duct.py
duct.py copied to clipboard
Would PR_SET_CHILD_SUBREAPER help for reliably killing grandchildren?
Maybe something like forking, calling prctl(PR_SET_CHILD_SUBREAPER) in the forked process and then running the command from this forked process would help with reliably killing grandchildren. I think you could then kill all the command with all children and grandchildren by killing all children of the forked process until no children are left. Normally when a parent process dies, all children get init as new parent. PR_SET_CHILD_SUBREAPER instead causes the process which called it to be the new parent for all childprocesses and their children of the process using this syscall if a parent process dies. This also means that this process is responsible for calling wait on all zombie childprocesses when it receives SIGCHLD. I haven't actually checked if this scheme works though.
Edit: others also suggested this on HN. Should have scrolled down a bit. 🤦
more complete Linux only solution explained in https://catern.com/ideas.html implemented in https://github.com/catern/supervise
I could be mistaken, but my impression is that using PR_SET_CHILD_SUBREAPER means the process needs to be prepared to handle SIGCHILD from grandchild processes. But my assumption has been that setting / relying on global signal handllers is a non-starter for a library, which might need to run in-process with any number of other libraries with similar ideas. Curious to get folks' thoughts.
I think that's right, but I believe
- python doesn't install a
SIGCHLDhandler (except inmultiprocessing.forkserver, but does duct really need to be compatible with that?) SIGCHLD's disposition is ignore
so I think most cases would be handled by PR_SET_CHILD_SUBREAPER
IMO, the main argument for this is: it seems reasonable to say that you can mess with SIGCHLD or use a library like duct that manages subprocesses for you, but not both