字符串的不变性和并发性
问题:
我们应该同步对字符串的写入吗?既然字符串是不可变的,那么我们不是可以保证多线程读写之间的状态一致吗?
答案:
Go 中的字符串值确实是不可变的,这意味着它们的内容一旦创建就无法修改。但是,这种不变性仅适用于字符串值本身,不适用于保存字符串的变量。
变量是可变的,并且可以随着时间的推移指向不同的字符串值。如果多个 goroutine 同时访问一个字符串变量,并且至少有一个 goroutine 写入该变量,则需要同步。这可确保按顺序执行对变量的写入,从而防止并发访问字符串的变量,而不是其值。
示例:
考虑以下代码:
<code class="go">var s string = "hello" func writeToString(s string) { s = "goodbye" } func main() { wg := sync.WaitGroup{} const num = 10 for i := 0; i < num; i++ { wg.Add(1) go func(i int) { defer wg.Done() writeToString(s) }(i) } wg.Wait() fmt.Println(s) }</code>
如果没有同步,此代码将导致数据竞争,因为多个 goroutine 正在写入保存字符串的变量。因此,s 的最终值可以是“hello”或“goodbye”,具体取决于哪个 goroutine 最后访问了该变量。
通过使用同步,例如sync.Mutex,我们确保只有一个 goroutine 可以一次写入变量,从而保留预期的行为。
以上是Go 中的不可变字符串是否需要同步并发写入?的详细内容。更多信息请关注PHP中文网其他相关文章!