how to close a child process after father process be killed

961 views
Skip to first unread message

Yulei Xiao

unread,
Apr 14, 2016, 10:33:32 PM4/14/16
to golang-nuts
I use exec.Command() to start a child process. After the father process is killed by "kill -9", the child process still running. 

Is there anyway to shutdown child process immediately after father process die?

Ian Lance Taylor

unread,
Apr 15, 2016, 1:05:37 AM4/15/16
to Yulei Xiao, golang-nuts
If you are using GNU/Linux, set the Pdeathsig field of the SysProcAttr struct.

Otherwise, as far as I know, there is no way.

Ian

Konstantin Khomoutov

unread,
Apr 15, 2016, 2:59:54 PM4/15/16
to Yulei Xiao, golang-nuts
In addition to what Ian said, you might consider doing this in some
other way. First, POSIX defines the concept of "process groups", which
are used to control processes in groups. Say, shells place all
processes participating in a pipeline, in the same process groups.
Each job started by a shell is in its own process group. The main
feature of a process group is that you're able to send a singal to the
whole PG. If interested, please check out setpgid(2) and killpg(2)
manual pages.

Another, Linux-specific, approach is cgroups (which are gaining
momentum along with light-weight virtualization, like LXC).
I have no experience with them but one of their much-touted feature is
that bringing down a specific cgroup is guaranteed to kill all the
processes associated with it, and there's no way for a process to
escape this (as is the case with process groups).

Of course, all of the above assumes you yourself want to explicitly
bring the whole hierarchy of the processes you have started. If the
question was really about taking down the child processes of a process
someone else killed, then there's no generic solution, I'm afraid.

yu didi

unread,
Jul 5, 2023, 10:37:02 AM7/5/23
to golang-nuts
Is there any way to create a child process that is detached from the original cgroup using exec.Command? I don't want my child process to be killed when the parent process dies. I have already detached 29324 and 29258 from their parent-child relationship because I started the cms process by executing exec.Command("bash", "-c", "nohup sleep 3s; cd /root; ./cms") within the cms process itself. I want to detach the spawned process, 29324, from the current cgroup: /system.slice/supervisord.service Note that at this point, there is no parent-child relationship between 29258 and 29324, meaning 29324 is not being supervised by supervisor. However, both processes are in the same cgroup. Then, when I execute pkill supervisor to kill the supervisor process, based on what you said about cgroup behavior, the cms process 29324 also gets killed. I want the cms process to not be killed. So, I hope there is a way for exec.Command to create a child process that is detached from the original cgroup. I have only come across the Unshare flags configuration, which seems like it can achieve this because it allows setting unix.CLONE_NEWCGROUP. However, I tried it and it didn't work, and I am executing the program with root privileges.

[root@@localhost ~]# systemctl status supervisord
● supervisord.service - Process Monitoring and Control Daemon
   Loaded: loaded (/usr/lib/systemd/system/supervisord.service; disabled; vendor preset: disabled)
   Active: active (running) since 三 2023-06-28 17:34:06 CST; 1min 30s ago
  Process: 29255 ExecStart=/usr/bin/supervisord -c /etc/supervisord.conf (code=exited, status=0/SUCCESS)
 Main PID: 29258 (supervisord)
   CGroup: /system.slice/supervisord.service
           ├─29258 /usr/bin/python /usr/bin/supervisord -c /etc/supervisord.conf
           └─29324 /root/cms

Brian Candler

unread,
Jul 5, 2023, 11:23:16 AM7/5/23
to golang-nuts
Is there any way to create a child process that is detached from the original cgroup using exec.Command?
I don't want my child process to be killed when the parent process dies.

This might be an issue with process groups, not cgroups, in which case I think Setsid is what you want, something like (untested):

        p.theCommand.SysProcAttr = &syscall.SysProcAttr{Setsid: true}
        err := p.theCommand.Start()

I had a related problem: I wanted to make sure that when a timeout occurs, I forcibly kill the child process and all its descendants. Solution was to use Setsid, and then send the signal to the newly-formed process group:

Peter Galbavy

unread,
Jul 6, 2023, 3:12:33 AM7/6/23
to golang-nuts
Yes, setsid combined with cmd.Process.Release() works for me.

My local / specific needs code is https://github.com/ITRS-Group/cordial/blob/ad18bfbfa44eff1b9b66408394dd83749da25bb1/pkg/process/process.go#L64 which works well for everything I have thrown at it (on Linux).

haipeng pan

unread,
Jan 14, 2025, 8:27:48 AMJan 14
to golang-nuts
On Windows, The Setsid does not exist, so I use the Windows Job Object to perform this. Here is my demostration, hope to help others.
Reply all
Reply to author
Forward
0 new messages