Hi, I wonder why the two programs below have different behaviors? Both start `yes` command, close write side of the pipe (because the main process doesn't use it), and read from the read side of the pipe. The only difference is one doesn't use goroutine and another uses it.
1) The first program doesn't use goroutine. It works as expected (you'll need to press Ctl-C to temrinate the program). ``` package main import ( "io" "os" "os/exec" ) func main() { rpipe, wpipe, err := os.Pipe() if err != nil { panic(err) } cmd := exec.Command("yes") cmd.Stdout = wpipe if err := cmd.Start(); err != nil { panic(err) } wpipe.Close() if _, err := io.Copy(os.Stdout, rpipe); err != nil { panic(err) } } ``` 2) The second program is almost same as the first one, except that it wraps the `yes` command related code in a goroutine. It fails to read data from pipe. The culprit is `wpipe.Close()` line. ``` package main import ( "io" "os" "os/exec" "fmt" ) func main() { rpipe, wpipe, err := os.Pipe() if err != nil { panic(err) } go func() { cmd := exec.Command("yes") cmd.Stdout = wpipe if err := cmd.Start(); err != nil { panic(err) } }() // Commenting out this line would make the program works fine. Why? wpipe.Close() n, err := io.Copy(os.Stdout, rpipe) if err != nil { panic(err) } fmt.Printf("n: %d", n) } // Output: // n: 0 ``` Question 1: I wonder why the above code doesn't work? I find two ways to make it work: 1) Remove `wpipe.Close()` line. I don't like this approach because I think it's a convention in Unix programs to close unused file descriptors. 2) Move `wpipe.Close()` to the goroutine. Question 2: Why does this work? Thanks for any explanation. -- 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+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/golang-nuts/e175827f-0159-4a2d-8d59-1cad48661002n%40googlegroups.com.