go - io.Pipe 中的竞争条件?

标签 go io race-condition

我有一个函数返回 io.PipeReader 端并启动一个将数据写入 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/

相关文章:

go - 如何获取golang中两个目录内容之间的差异

http - 服务器的 Golang 自定义处理程序

list - Haskell IO 创建一个字符串列表并显示它

go - 在 select 语句中使用 Reader 接口(interface)时的约定

go - 使用 Go 客户端获取 Kubernetes 中 pod 的当前资源使用情况

c - _findfirst 失败,路径为 ..

c - 在C程序中获取系统命令输出

java - 此代码是否线程安全,使用 Java 8 Lambdas - stream.forEach

mysql - 使用由两个连接读取和递增的计数器时如何避免竞争条件?

javascript - 保证在 evalAsync 完成后运行