【问题标题】:Golang's bytes.Buffer thread safety for one writer/one readerGolang 的 bytes.Buffer 线程安全,适用于一位作者/一位读者
【发布时间】:2017-02-24 17:57:42
【问题描述】:

我知道 golang 的 bytes.Buffer 不是线程安全的,但如果我有一个编写器(在一个 goroutine 中)和一个阅读器(在另一个 goroutine 中)。安全吗?

如果不是,那为什么不是呢?写入追加到缓冲区,而读取从头开始读取,所以我看不到他们将访问相同内存位置的情况。

【问题讨论】:

    标签: go io buffer slice


    【解决方案1】:

    不,这不安全。

    bytes.Buffer 是一个结构,Buffer.Read()Buffer.Write() 方法都读取/修改相同结构值的相同字段(它们具有指针接收器)。仅此一项就足以使并发使用不安全。更多详情请见Is it safe to read a function pointer concurrently without a lock?

    还可以考虑bytes.Buffer 将字节存储在字节片中,这是结构体的一个字段。写入时,有时可能需要分配更大的缓冲区(如果切片容量不够),因此必须更改切片头(切片结构字段)(在Write() 中)。如果没有同步,就不能保证并发的Read() 会看到这个。

    而且...即使不需要重新分配(因为底层字节切片有足够的容量来容纳传递给Write()的数据),将数据存储在字节切片中也需要对其进行重新切片,因此切片头会发生变化即使不需要重新分配(切片的长度也是切片头的一部分)。要查看切片标头中的内容,请查看 reflect.SliceHeader 类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多