Connected readers and writers

The io.Pipe function creates a pair of readers and writers that are connected. This means that whatever is sent to the writer will be received from the reader. Write operations are blocked if there is still data that is hanging from the last one; only when the reader has finished consuming what has been sent will the new operation be concluded.

This is not an important tool for non-concurrent applications, which are more likely to use concurrent tools such as channels, but when the reader and writer are executing on different goroutines, this can be an excellent mechanism for synchronization, as in the following program:

    pr, pw := io.Pipe()
go func(w io.WriteCloser) {
for _, s := range []string{"a string", "another string",
"last one"} {
fmt.Printf("-> writing %q\n", s)
fmt.Fprint(w, s)
}
w.Close()
}(pw)
var err error
for n, b := 0, make([]byte, 100); err == nil; {
fmt.Println("<- waiting...")
n, err = pr.Read(b)
if err == nil {
fmt.Printf("<- received %q\n", string(b[:n]))
}
}
if err != nil && err != io.EOF {
fmt.Println("error:", err)
}

The full example is available at https://play.golang.org/p/0YpRK25wFw_c.