我有一个函数返回 io.Pipe
的 Reader
端并启动一个将数据写入 Writer
的 go-routine > 结束,然后关闭管道。
func GetPipeReader() io.ReadCloser {
r, w := io.Pipe()
go func() {
_, err := io.CopyN(w, SomeReaderOfSize(N), N)
w.CloseWithError(err)
}()
return r
}
func main() {
var buf bytes.Buffer
io.Copy(&buf, GetPipeReader())
println("got", buf.Len(), "bytes")
}
https://play.golang.org/p/OAijIwmtRr
这在我的测试中似乎总是有效,因为我得到了我写的所有数据。但是 API docs让我有点担心:
func Pipe() (*PipeReader, *PipeWriter)
Pipe creates a synchronous in-memory pipe. [...] Reads on one end are matched with writes on the other, [...] there is no internal buffering.
func (w *PipeWriter) CloseWithError(err error) error
CloseWithError closes the writer; subsequent reads from the read half of the pipe will return no bytes and the error err, or EOF if err is nil.
我想知道的是,这里可能的竞争条件是什么?我的 go-routine 会写入一堆数据,然后在我读取所有数据之前关闭管道,这是否合理?
我是否需要使用 channel 来发出何时关闭的信号?基本上会出什么问题。
最佳答案
不,没有竞争条件。正如文档中提到的,一端的读取与另一端的写入相匹配。因此,当到达 CloseWithError()
时,这意味着每个 Write
已成功完成并与相应的 Read
匹配 - 所以另一端必须已阅读该阅读的所有内容。
关于go - io.Pipe 中的竞争条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34063291/