Go에서 동기화를 보장하기 위해 wg.Add() 배치가 중요한 이유는 무엇입니까?

DDD
풀어 주다: 2024-10-27 20:40:03
원래의
637명이 탐색했습니다.

Why is wg.Add() Placement Crucial for Guaranteed Synchronization in Go?

동기화 보장을 위한 wg.Add() 위치

문제

아래 Go 코드에서 변수 v는 종종 예상보다 작습니다. wg.Add()의 잘못된 배치에 대해.

<code class="go">var wg sync.WaitGroup
var v int32 = 0
for i := 0; i < 100; i++ {
    go func() {
        wg.Add(1) // Wrong place
        atomic.AddInt32(&v, 1)
        wg.Done()
    }
}
wg.Wait()
fmt.Println(v)</code>
로그인 후 복사

해결 방법

wg.Add()는 해당 고루틴을 시작하기 전에 항상 호출되어야 합니다. 고루틴이 wg.Done()을 실행했습니다.

<code class="go">var wg sync.WaitGroup
var v int32 = 0
for i := 0; i < 100; i++ {
    wg.Add(1)
    go func() {
        atomic.AddInt32(&v, 1)
        wg.Done()
    }
}
wg.Wait()
fmt.Println(v)</code>
로그인 후 복사

설명

wg.Add()가 고루틴 내부에 배치되면 모든 고루틴이 완료될 때까지 기본 고루틴이 차단된다는 것을 보장할 수 없습니다. . 이는 고루틴이 동시에 실행되고 실행 순서가 비결정적이기 때문입니다.

wg.Add()를 고루틴 앞에 배치하여 기본 고루틴이 도달하기 전에 wg.Add()를 100번 호출하도록 보장합니다. wg.잠깐(). 이렇게 하면 100개의 고루틴이 모두 wg.Done()을 호출할 때까지 기본 고루틴이 차단되어 v가 일관되게 100이 됩니다.

모범 사례

sync.WaitGroup을 사용할 때 다음을 따르세요. 지침:

  • go를 사용하여 새 고루틴을 시작하기 전에 "원래" 고루틴에서 wg.Add()를 호출하세요.
  • wg.Done()을 호출하려면 defer 문을 사용하세요. 고루틴 패닉이 발생하더라도 호출됩니다.
  • wg를 다른 함수에 전달할 때 wg 구조체의 복사본이 생성되지 않도록 포인터를 전달하세요.

위 내용은 Go에서 동기화를 보장하기 위해 wg.Add() 배치가 중요한 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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