Golang的bytes.Buffer线程安全性为一个作家/一个读者

时间:2017-02-24 17:57:43

标签: go io buffer slice

我知道golang的bytes.Buffer不是线程安全的,但如果我有一个作家(在goroutine中)和一个读者(在另一个goroutine中)。这样安全吗?

如果没有,那为什么不呢?写入从缓冲区读取,同时从头开始读取,因此我没有看到他们将访问相同内存位置的情况。

1 个答案:

答案 0 :(得分:9)

不,这不安全。

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类型。