> 백엔드 개발 > Golang > Go 구조체에 대한 동시 읽기 및 쓰기 작업이 어떻게 데이터 경합으로 이어질 수 있습니까?

Go 구조체에 대한 동시 읽기 및 쓰기 작업이 어떻게 데이터 경합으로 이어질 수 있습니까?

Linda Hamilton
풀어 주다: 2024-12-30 09:59:18
원래의
659명이 탐색했습니다.

How Can Concurrent Read and Write Operations on Go Structs Lead to Data Races?

Go Struct 동시 읽기 및 쓰기: 데이터 경합이 발생할 수 있는 이유

Go에서 잠금이 없는 구조에 대한 동시 읽기 및 쓰기 작업은 잠재적으로 데이터 경쟁으로 이어집니다. 이로 인해 항상 치명적인 오류가 발생하는 것은 아니지만 근본적인 문제를 이해하는 것이 중요합니다.

구조의 데이터 경합 문제

여러 고루틴이 동시에 실행될 때 데이터 경합이 발생합니다. 공유 변수에 액세스하고 해당 액세스 중 적어도 하나는 쓰기입니다. 구조의 경우, 이는 두 개 이상의 고루틴이 동시에 동일한 구조의 서로 다른 필드를 읽거나 쓸 수 있음을 의미합니다.

여러 고루틴이 동시에 메타데이터 구조를 읽고 쓰는 다음 예를 생각해 보세요. :

type Metadata struct {
    key bool
}

func concurrentStruct() {
    m := new(Metadata)

    for i := 0; i < 100000; i++ {
        go func(metadata *Metadata) {
            for {
                readValue := metadata.key
                if readValue {
                    metadata.key = false
                }
            }
        }(m)

        go func(metadata *Metadata) {
            for {
                metadata.key = true
            }
        }(m)
    }
    select {}
}
로그인 후 복사

이 예제는 WARNING: DATA RACE와 함께 실행되지만 치명적인 오류가 발생하지는 않습니다. 이는 데이터 경합이 구조의 단일 필드(키 필드)에서만 발생하기 때문입니다. 다른 필드에 액세스하지 않으므로 구조가 안정적으로 유지되고 프로그램을 계속 실행할 수 있습니다.

데이터 경합 해결

데이터 경합을 제거하려면 다음을 수행해야 합니다. 잠금을 사용하여 구조에 대한 동시 액세스를 동기화합니다. 이를 달성하는 한 가지 방법은 다음 예와 같이 읽기-쓰기 뮤텍스를 사용하는 것입니다.

type Metadata struct {
    mu  sync.RWMutex
    key bool
}

func concurrentStructWithMuLock() {
    m := new(Metadata)

    go func(metadata *Metadata) {
        for {
            metadata.mu.Lock()
            readValue := metadata.key
            if readValue {
                metadata.key = false
            }
            metadata.mu.Unlock()
        }
    }(m)

    go func(metadata *Metadata) {
        for {
            metadata.mu.Lock()
            metadata.key = true
            metadata.mu.Unlock()
        }
    }(m)
    select {}
}
로그인 후 복사

읽기-쓰기 뮤텍스를 추가하면 데이터 경쟁이 제거되고 프로그램이 실행됩니다. 오류 메시지 없이. 이는 뮤텍스가 한 번에 하나의 고루틴만 구조에 액세스할 수 있도록 보장하기 때문입니다.

결론적으로 Go의 구조에 대한 동시 읽기 및 쓰기 작업은 구조에 여러 필드가 있어도 데이터 경합이 발생할 수 있습니다. 데이터 경합을 방지하고 동시 프로그램의 올바른 작동을 보장하려면 읽기-쓰기 뮤텍스와 같은 동기화 메커니즘을 사용하는 것이 중요합니다.

위 내용은 Go 구조체에 대한 동시 읽기 및 쓰기 작업이 어떻게 데이터 경합으로 이어질 수 있습니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿