>백엔드 개발 >Golang >Go 채널에서 WaitGroup을 값으로 전달하면 교착 상태가 발생하는 이유는 무엇입니까?

Go 채널에서 WaitGroup을 값으로 전달하면 교착 상태가 발생하는 이유는 무엇입니까?

Mary-Kate Olsen
Mary-Kate Olsen원래의
2024-10-31 04:59:02462검색

Why does passing a WaitGroup by value in Go channels lead to a deadlock?

참조 전달로 인한 Go 채널의 교착 상태

Go에서 채널은 강력한 통신 메커니즘이지만 그렇지 않으면 교착 상태로 이어질 수 있습니다. 올바르게 사용되었습니다. 두 개 이상의 고루틴이 서로 작업이 완료되기를 기다리고 있어 어느 고루틴도 진행할 수 없을 때 교착 상태가 발생합니다.

다음 Go 프로그램을 고려하세요.

<br>패키지 메인</p>
<p>import (</p>
<pre class="brush:php;toolbar:false">"fmt"
"sync"

)

func push(c chan int, wg sync.WaitGroup) {

for i := 0; i < 5; i++ {
    c <- i
}
wg.Done()

}

func pull(c chan int, wg sync.WaitGroup) {

for i := 0; i < 5; i++ {
    result, ok := <-c
    fmt.Println(result, ok)
}
wg.Done()

}

func main() {

var wg sync.WaitGroup
wg.Add(2)
c := make(chan int)

go push(c, wg)
go pull(c, wg)

wg.Wait()

}

이 프로그램을 실행하면 교착 상태 오류로 인해 패닉이 발생합니다.

throw: all goroutines are asleep - deadlock!

문제는 WaitGroup이 고루틴에 전달되는 방식에 있습니다. . Go에서 구조체는 값으로 전달됩니다. 즉, WaitGroup의 복사본이 각 고루틴에 전달됩니다. 하나의 고루틴이 복사본에서 Done을 ​​호출하면 기본 함수에서 생성된 원래 WaitGroup에 아무런 영향을 주지 않습니다.

교착 상태를 해결하려면 값 대신 WaitGroup 포인터를 전달해야 합니다. 수정된 코드는 다음과 같습니다.

<br>package main</p><p>import (</p><pre class="brush:php;toolbar:false">"fmt"
"sync"

)

func push(c chan int , wg *sync.WaitGroup) {

for i := 0; i < 5; i++ {
    c <- i
}
wg.Done()

}

func pull(c chan int, wg *sync.WaitGroup) {

for i := 0; i < 5; i++ {
    result, ok := <-c
    fmt.Println(result, ok)
}
wg.Done()

}

func main() {

var wg sync.WaitGroup
wg.Add(2)
c := make(chan int)

go push(c, &wg)
go pull(c, &wg)

wg.Wait()

}

값 대신 WaitGroup 포인터를 전달하면 두 고루틴 모두 동일한 항목에 액세스할 수 있습니다. WaitGroup 인스턴스. 하나의 고루틴이 Done을 ​​호출하면 원래 WaitGroup의 카운트가 감소하여 다른 고루틴이 진행될 수 있도록 합니다.

위 내용은 Go 채널에서 WaitGroup을 값으로 전달하면 교착 상태가 발생하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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