【问题标题】:Why doesn't os/exec.CombinedOutput() have a race condition?为什么 os/exec.CombinedOutput() 没有竞争条件?
【发布时间】:2017-03-31 10:36:47
【问题描述】:

Go bytes.Buffer isn't thread-safe。然而,当我阅读源代码时,我注意到os/exec.CombinedOutput()c.Stdoutc.Stderr 使用相同的缓冲区。进一步阅读包的实现,在写入c.Stderr/c.Stdouthere时似乎没有同步。

是我遗漏了什么还是发现了可能的同步问题?子进程可以同时写入 AFAIK 标准错误和标准输出。

【问题讨论】:

    标签: go thread-safety


    【解决方案1】:

    如果Stderr 和Stdout 是Cmd documentation 中所述的同一写入器,则它们不会同时写入:

    如果 Stdout 和 Stderr 是同一个 writer,一次最多有一个 goroutine 会调用 Write。

    此功能在Cmd.stderr 函数中实现。如果 Stdout 和 Stderr 相同,则将相同的 fd 传递给子进程 stdout 和 stderr。在 fd 是一个带有 goroutine 的管道的情况下,只有一个 goroutine 写入 Stdout/Stderr。

    【讨论】:

    • 这里的文档有点误导,因为当作者无法比较时,仍然可能存在竞争条件。文档可能应该更新,以便更清楚地了解 Stdout 和 Stderr 何时被视为“相同”。我为此填写了golang.org/issue/19804