Go 채널의 교착 상태
Go에서 채널은 고루틴 간의 통신 수단을 제공합니다. 그러나 채널을 부적절하게 사용하면 고루틴이 무기한 차단되는 교착 상태가 발생할 수 있습니다.
채널 교착 상태의 일반적인 원인 중 하나는 고루틴 함수에서 포인터 대신 값 유형을 전달할 때입니다. 이는 Go가 값별로 값 유형을 전달하기 때문입니다. 즉, 값의 복사본이 생성됩니다.
다음 예를 고려하세요.
<code class="go">import ( "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() }</code>
프로그램을 실행하면 교착 상태 오류가 발생합니다.
0 true 1 true 2 true 3 true 4 true throw: all goroutines are asleep - deadlock!
WaitGroup이 push 및 pull 함수에 값으로 전달되기 때문에 교착 상태가 발생합니다. WaitGroup이 고루틴 중 하나에서 업데이트되면 값의 복사본이 있기 때문에 변경 사항이 다른 고루틴에 반영되지 않습니다.
교착 상태를 해결하려면 WaitGroup을 포인터로 전달해야 합니다. 이는 두 고루틴이 WaitGroup의 동일한 인스턴스에서 작동하도록 보장합니다.
수정된 코드 버전은 다음과 같습니다.
<code class="go">import ( "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() }</code>
위 내용은 포인터 대신 값을 전달하면 Go 채널에서 교착 상태가 발생하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!