>백엔드 개발 >Golang >GO:동기화 부족

GO:동기화 부족

Linda Hamilton
Linda Hamilton원래의
2024-11-30 01:10:11514검색

GO:lack of synchronization

var a string
var done bool

func setup() {
    a = "hello, world"
    done = true
}

func doprint() {
    if !done {
        once.Do(setup)
    }
    print(a)
}

func twoprint() {
    go doprint()
    go doprint()
}

코드 분석

변수:

  • a와 b는 모든 고루틴에서 공유하는 int 유형의 전역 변수입니다.

기능:

  • 에프():
    • a와 b에 순차적으로 씁니다(a = 1 및 b = 2).
  • g():
  • b 다음에 a가 오는 것을 읽고 인쇄합니다.

main()의 동시성:

  • f() 함수는 go f()를 사용하여 별도의 고루틴으로 실행됩니다.
  • g() 함수는 메인 고루틴에서 직접 실행됩니다.

잠재적인 문제:

  • f()를 실행하는 고루틴과 g()를 실행하는 기본 고루틴은 동시에 실행됩니다.
  • g()가 a와 b의 값을 읽고 인쇄하기 전에 f()의 a와 b에 대한 쓰기가 완료되지 않을 수 있습니다.
  • 이로 인해 동기화 없이 공유 메모리(a ​​및 b)에서 동시 액세스(f()에서 쓰기 및 g()에서 읽기)가 발생하는 데이터 경쟁이 발생합니다.

가능한 결과
동기화가 부족하기 때문에 프로그램의 출력은 비결정적입니다. 가능한 시나리오는 다음과 같습니다.

사례 1: f()가 a와 b를 수정하기 전에 g()가 실행됩니다.

  • a와 b의 초기 값은 0입니다(Go에서 초기화되지 않은 int의 기본값).
0
0

또는

사례 2: g() 전에 b = 2가 완료되었지만 a = 1이 완료되지 않은 경우 출력은 다음과 같습니다.

2
0

주요 관찰
데이터 경쟁: 동기화 없이 a와 b에 동시에 액세스하면 데이터 경쟁이 발생합니다. 이로 인해 프로그램의 동작이 정의되지 않고 예측할 수 없게 됩니다

코드 수정

  1. sync.WaitGroup 사용: g()가 실행되기 전에 f()가 완료되는지 확인하세요.
var a, b int
var wg sync.WaitGroup

func f() {
    a = 1
    b = 2
    wg.Done()
}

func g() {
    print(b)
    print(a)
}

func main() {
    wg.Add(1)
    go f()
    wg.Wait()
    g()
}

  1. 채널 사용: f()가 완료되면 신호를 보냅니다.
var a, b int

func f(done chan bool) {
    a = 1
    b = 2
    done <- true
}

func g() {
    print(b)
    print(a)
}

func main() {
    done := make(chan bool)
    go f(done)
    <-done
    g()
}

여기서 g()는 f()가 완료된 채널을 통해 신호를 보낼 때까지 기다립니다.

위 내용은 GO:동기화 부족의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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