Golang的bytes.Buffer对于一个写者/读者的线程安全性

3
我知道golang中的bytes.Buffer不是线程安全的,但如果我有一个写入者(在一个goroutine中)和一个读取者(在另一个goroutine中),这是安全的吗?
如果不安全,那么为什么不安全?写操作将向缓冲区追加数据,而读操作从开头读取,因此我看不到它们会访问相同的内存位置的情况。
1个回答

9
不,这是不安全的。 bytes.Buffer 是一个结构体,Buffer.Read()Buffer.Write() 方法都读取/修改同一结构体值的相同字段(它们有指针接收器)。仅此就足以使并发使用变得不安全。更多细节请参见在没有锁的情况下同时读取函数指针是否安全? 此外,请考虑 bytes.Buffer 将字节存储在字节切片中,该切片是结构体的一个字段。写入时,可能需要有时分配更大的缓冲区(如果切片容量不够),因此必须更改切片头(切片结构字段)(在Write()中)。没有同步,不能保证并发的 Read() 将看到这个变化。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接