Race condition with Exec

401 views
Skip to first unread message

charmes....@gmail.com

unread,
Jul 30, 2013, 7:05:24 PM7/30/13
to golan...@googlegroups.com
Hello,

I am trying to monitor a process using os/exec.Cmd but when I try to Wait(), I always face a race.

I have a very basic code that works fine:
When I quit cat with ctrl-d, the program exits as expected.

However, when I try to close manually, the race detector is not happy:

This is exactly the same thing except that after 5 seconds I close stdin.

Then I tried using the StdinPipe() from Cmd, but still not luck:

Is there a way to do Cmd.Wait() and close Stdin without a race?

Thanks in advance.

Regards,
-- 
Guillaume J. Charmes

Dmitry Vyukov

unread,
Jul 31, 2013, 2:50:42 PM7/31/13
to charmes....@gmail.com, golang-nuts
I think you need to close the file after starting the process.
> --
> 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.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

Guillaume J. Charmes

unread,
Jul 31, 2013, 4:40:50 PM7/31/13
to Dmitry Vyukov, golang-nuts
I am trying to monitor the process. I need to close stdin in a different goroutine, so I need to Cmd.Wait() on the process.

-- 
Guillaume J. Charmes

Dmitry Vyukov

unread,
Jul 31, 2013, 5:49:39 PM7/31/13
to Guillaume J. Charmes, golang-nuts
I mean:
cmd.Start()
time.AfterFunc(5*time.Second, func() { os.Stdin.Close() })
cmd.Wait()

Otherwise you are closing the pipe before starting the process, and
cmd.Start can not even reliably read fd that you are passing in.

Guillaume J. Charmes

unread,
Jul 31, 2013, 5:56:13 PM7/31/13
to Dmitry Vyukov, golang-nuts
Indeed, my bad on this example.

However, in the last example, the close is done after the start.



-- 
Guillaume J. Charmes

Dmitry Vyukov

unread,
Aug 1, 2013, 6:03:23 AM8/1/13
to Guillaume J. Charmes, golang-nuts
On Thu, Aug 1, 2013 at 1:56 AM, Guillaume J. Charmes
<charmes....@gmail.com> wrote:
> Indeed, my bad on this example.
>
> However, in the last example, the close is done after the start.
>
> http://play.golang.org/p/UfaX8dQbdR


The following works:

cmd := exec.Command("zcat", "-f")
cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin
cmd.Start()
cmd.Wait()

There is not much you can do with stdin/stdout while the command runs,
because it accesses them concurrently. OR your stdin/stdout must be
completely thread-safe, e.g. net.Conn.

Dmitry Vyukov

unread,
Aug 1, 2013, 6:18:41 AM8/1/13
to Guillaume J. Charmes, golang-nuts
I've filed https://code.google.com/p/go/issues/detail?id=6008
to clarify the documentation. I do not understand it all as well.

roger peppe

unread,
Aug 1, 2013, 9:39:05 AM8/1/13
to Dmitry Vyukov, Guillaume J. Charmes, golang-nuts
See issue 4290.
I agree entirely - this is highly unintuitive behaviour
but we can't change it now. Suggestions for
documentation re-wording would be good.
Reply all
Reply to author
Forward
0 new messages