Starting detached child process

9,002 views
Skip to first unread message

Hein Meling

unread,
Jul 17, 2014, 9:13:10 PM7/17/14
to golan...@googlegroups.com
Hi

I've been spending my day looking for a way to start child processes from a Go program (the parent) such that, if the parent process dies, the children doesn't. I tried using 'nohup' as a go-between, but can't seem to start the child processes in the background. Are there any recommended (or reasonable) work-arounds for this?

Thanks,
:) Hein

Shawn Milochik

unread,
Jul 17, 2014, 9:15:35 PM7/17/14
to golan...@googlegroups.com
It looks like exec.Start() does what you want.



Hein Meling

unread,
Jul 17, 2014, 9:56:40 PM7/17/14
to Sh...@milochik.com, golan...@googlegroups.com
No, because if the go program (the parent) is killed, the children also gets killed.

Hein :)

Sent from my iPad

On 17 Jul 2014, at 18:15, Shawn Milochik <shawn...@gmail.com> wrote:

It looks like exec.Start() does what you want.



--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/shST-SDqIp4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Shawn Milochik

unread,
Jul 17, 2014, 10:04:25 PM7/17/14
to golan...@googlegroups.com
On Thu, Jul 17, 2014 at 9:56 PM, Hein Meling <hein....@gmail.com> wrote:
No, because if the go program (the parent) is killed, the children also gets killed.

Hein :)



That doesn't seem to be the case.

package main

import (
    "os/exec"
)

func main() {
    cmd := exec.Command("/tmp/monkey.sh")
    cmd.Start()
}

When I run that, with monkey.sh  being a program  that just appends text to a file, it keeps running after the Go program exits. I can even run the Go program multiple times and multiple instances of monkey.sh are running.

 

Hein Meling

unread,
Jul 17, 2014, 11:12:30 PM7/17/14
to golan...@googlegroups.com, sh...@milochik.com
Your solution seems to work when then parent process exits cleanly. But if you do:

func main() {
cmd := exec.Command("sleep", "15")
cmd.Start()
time.Sleep(20 * time.Second)
}

And CTRL-C the parent process before it exits cleanly, then also the sleep process goes away. Does the same happen to your monkey.sh process?

Moreover, my use case is actually somewhat more involved. That is, I would like to do cmd.Wait() (from different goroutines), in order to monitor the child processes, but I don't want the child processes to fail if the parent fails. 

:) Hein

Bryan Whitehead

unread,
Jul 18, 2014, 3:27:59 AM7/18/14
to Hein Meling, golang-nuts, sh...@milochik.com
You need to use os/signal to intercept SIGKILL or SIGTERM and exit cleanly so your children continue to live.


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.

Ian Lance Taylor

unread,
Jul 18, 2014, 4:07:44 AM7/18/14
to Hein Meling, golang-nuts, sh...@milochik.com
On Thu, Jul 17, 2014 at 8:12 PM, Hein Meling <hein....@gmail.com> wrote:
>
> Your solution seems to work when then parent process exits cleanly. But if
> you do:
>
> func main() {
> cmd := exec.Command("sleep", "15")
> cmd.Start()
> time.Sleep(20 * time.Second)
> }
>
> And CTRL-C the parent process before it exits cleanly, then also the sleep
> process goes away. Does the same happen to your monkey.sh process?
>
> Moreover, my use case is actually somewhat more involved. That is, I would
> like to do cmd.Wait() (from different goroutines), in order to monitor the
> child processes, but I don't want the child processes to fail if the parent
> fails.

^C kills all the processes because on Unix typing ^C on the terminal
sends a signal to every process in the process group. So you want to
have a child process that is in a different process group. You do
that by setting Setpgid to true in the Cmd.SysProcAttr field.

Ian

Hein Meling

unread,
Jul 18, 2014, 11:06:42 AM7/18/14
to golan...@googlegroups.com, hein....@gmail.com, sh...@milochik.com
Thanks Ian, that worked as expected!!

:) Hein

calin...@gmail.com

unread,
Oct 20, 2015, 5:43:28 PM10/20/15
to golang-nuts, hein....@gmail.com, sh...@milochik.com
Setting Setpgid to true in Cmd.SysProcAttr works out great on platforms like OS X and Ubuntu (the only ones I tested on), but for some reason it doesn't appear to work on CentOS 7.1.1503 kernel version 3.10.0-229.4.2.el7.x86_64. Anyone else having this problem?

m...@tejas.io

unread,
Oct 17, 2016, 1:00:02 AM10/17/16
to golang-nuts, hein....@gmail.com, sh...@milochik.com
For some reason, this does not seem to work for `ssh` (at least on OS X) unless you have `ControlPath` in ssh config. Are there any side-effects of SysProcAttr that I could be missing?
Reply all
Reply to author
Forward
0 new messages