참조 전달로 인한 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!