>  기사  >  백엔드 개발  >  문자열이 불변임에도 불구하고 Go에서 문자열 변수에 대한 액세스를 동기화해야 하는 이유는 무엇입니까?

문자열이 불변임에도 불구하고 Go에서 문자열 변수에 대한 액세스를 동기화해야 하는 이유는 무엇입니까?

DDD
DDD원래의
2024-11-03 06:52:02314검색

Why Do I Need to Synchronize Access to String Variables in Go, Even Though Strings Are Immutable?

문자열의 불변성과 스레드 동기화

Go의 문자열은 불변이지만 해당 참조를 보유하는 변수는 그렇지 않습니다. 따라서 멀티스레드 환경에서 문자열을 작업할 때는 문자열 자체가 아닌 문자열 변수에 대한 액세스를 동기화해야 합니다.

문자열이 원자 형식으로 지정되지 않는 이유

원자 유형은 초기화 후에 해당 값이 수정되지 않도록 보장합니다. 그러나 문자열 변수는 재할당될 수 있으므로 문자열은 원자적으로 형식화되지 않습니다.

문자열 변수 동기화

여러 스레드가 문자열 변수에 액세스할 때마다 동기화가 필요합니다. 적어도 하나의 액세스는 쓰기입니다. 문자열 자체를 수정하는 것이 아니라 변수를 다시 할당해야만 문자열 값을 변경할 수 있기 때문입니다.

실습

문자열 값이 "hello"인 경우 "인 경우 변수에 새 값을 할당하지 않는다고 가정하면 무기한 "hello" 상태로 유지됩니다. 그러나 슬라이스 값 []byte{1, 2, 3}이 있는 경우 슬라이스가 값으로 전달되더라도 해당 요소는 동시에 수정될 수 있습니다.

다음 예를 고려하세요.

var sig = make(chan int)

func main() {
    s := []byte{1, 2, 3}
    go func() {
        <-sig
        s[0] = 100
        sig <- 0
    }()
    sliceTest(s)
}

func sliceTest(s []byte) {
    fmt.Println("First  s =", s)

    sig <- 0 // send signal to modify now
    <-sig    // Wait for modification to complete

    fmt.Println("Second s =", s)
}

출력:

First  s = [1 2 3]
Second s = [100 2 3]

이 예에서 SliceTest()는 슬라이스를 수신하고 초기 값을 인쇄합니다. 그런 다음 다른 고루틴이 슬라이스를 수정할 때까지 기다린 다음 수정된 값을 인쇄합니다. 이는 슬라이스 값이 동시에 변경될 수 있음을 보여줍니다. 그러나 SliceTest()가 문자열 인수를 수신하는 경우 이러한 수정은 발생하지 않습니다.

위 내용은 문자열이 불변임에도 불구하고 Go에서 문자열 변수에 대한 액세스를 동기화해야 하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.