Immutability of string and concurrency

后端 未结 3 817
说谎
说谎 2021-01-11 21:42

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?

3条回答
  •  天命终不由人
    2021-01-11 22:02

    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.

提交回复
热议问题