在Go中,在许多情况下,并发访问共享对象需要sync.Mutext
。但是,在某些情况下,我只对变量或字段的最新值感兴趣。还是我喜欢写一个值,不在乎另一个go例程以后是否覆盖它,还是以前才覆盖它。
这里是一个“正确”程序:
package main
import (
"fmt"
"time"
)
func main() {
var name string
for i := 0; i < 10; i++ {
go func(i int) {
name = fmt.Sprintf("name = %d", i)
}(i)
go func(i int) {
println("read:", name)
}(i)
}
time.Sleep(10 * time.Millisecond)
}
预期的输出变量:
read:
read: name = 3
read: name = 3
read: name = 5
read: name = 4
read: name = 4
read: name = 8
read: name = 9
read: name = 9
read: name = 9
在这种情况下,我会将read:
和read: name=[0-9]
的任意组合视为正确的输出。接收任何其他字符串作为输出将是错误。
[我知道对于map
类型,并且在附加到切片时,我始终需要互斥或类似的保护方法,以避免出现段错误或意外行为。但是,在不使用多文本的情况下,读写文字或字段值似乎是安全的。
问题:我可以安全地读取和安全地同时写入哪些Go数据类型,而无需使用mutext,不产生段错误以及不从内存中读取垃圾?
哪些Go数据类型可以安全地读取和安全地并发写入而无需使用mutext,不产生段错误以及不从内存中读取垃圾?
无。
真的很简单:无论如何在任何情况下都不能同时对Go中的任何内容进行读写。
(顺便说一句,您的“正确”程序不正确,它很讲究,即使您摆脱了竞争条件,它也不会确定地产生输出。)