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

Mary-Kate Olsen
풀어 주다: 2024-10-31 04:59:02
원래의
373명이 탐색했습니다.

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

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

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

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

<br>패키지 메인</p>
<p>import (</p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><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><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
이전 기사:Golang의 범위 외부에서 For 루프를 어떻게 중단할 수 있습니까? 다음 기사:Go에서 `*T`가 `T`에 대한 메소드를 사용할 수 없는 이유는 무엇입니까?
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
최신 이슈
관련 주제
더>
인기 추천
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!