Should we synchronize on writing strings? Since string is immutable we will never get inconsistent state between write and read from the 2 different threads, right?
Should we synchronize on writing strings? Since string is immutable we will never get inconsistent state between write and read from the 2 different threads, right?
That's the question. The answer is: synchronize on writing strings. It's clear that string variables are mutable and string contents are immutable, as I already explained earlier. To reiterate:
The Go compiler will enforce the immutability of string contents. For example,
package main
func main() {
var s string = "abc"
s[0] = '0'
}
Output:
5:7: cannot assign to s[0]
The Go runtime Data Race Detector flags the inconsistent state of mutable string variables updated from different goroutines. For example, writing to a string variable,
package main
import "time"
var s string = "abc"
func main() {
go func() {
for {
s = "abc"
}
}()
go func() {
for {
s = "abc"
}
}()
time.Sleep(1 * time.Second)
}
Output:
$ go run -race racer.go
==================
WARNING: DATA RACE
Write at 0x00000050d360 by goroutine 6:
main.main.func2()
/home/peter/src/racer.go:15 +0x3a
Previous write at 0x00000050d360 by goroutine 5:
main.main.func1()
/home/peter/src/racer.go:10 +0x3a
Goroutine 6 (running) created at:
main.main()
/home/peter/src/racer.go:13 +0x5a
Goroutine 5 (running) created at:
main.main()
/home/peter/src/racer.go:8 +0x42
==================
Found 1 data race(s)
exit status 66
$
Original Post:
The Go Programming Language Specification
String types
A string type represents the set of string values. A string value is a (possibly empty) sequence of bytes. Strings are immutable: once created, it is impossible to change the contents of a string.
A string variable is not immutable. It contains a string descriptor, a struct.
type stringStruct struct {
str unsafe.Pointer
len int
}
For example,
package main
import "fmt"
func main() {
s := "abc"
fmt.Println(s)
s = "xyz"
fmt.Println(s)
}
Output:
abc
xyz
The string contents are immutable. For example,
// error: cannot assign to s[0]
s[0] = '0'
You need synchronization for access to string variables.