WaitGroups를 사용한 Go 동시성 교착 상태 감지
Go에서는 고루틴을 조정하기 위해 채널 및 대기 그룹을 사용하여 동시성을 관리하는 경우가 많습니다. 그러나 교착 상태로 이어질 수 있는 잠재적 위험을 이해하는 것이 중요합니다.
문제 설명
버퍼 채널 및 대기 그룹을 사용하려고 시도하는 다음 코드를 고려하세요.
<code class="go">package main import ( "fmt" "sync" ) func main() { ch := make(chan []int, 4) var m []int var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func() { defer wg.Done() ch <- m // Send to channel return }() } wg.Wait() // Wait for all goroutines to complete for c := range ch { fmt.Printf("c is %v", c) // Iterate over channel } }</code>
용량에 도달하면 채널이 자동으로 닫힐 것으로 예상했음에도 불구하고 이 코드는 예기치 않게 교착 상태 오류를 발생시킵니다.
해결 방법
두 가지가 있습니다. 교착 상태로 이어지는 주요 문제:
교착 상태를 해결하기 위한 두 가지 솔루션은 다음과 같습니다.
솔루션 1: 채널 용량 확장 및 명시적 닫기
<code class="go">ch := make(chan []int, 5) // Increase channel capacity ... wg.Wait() close(ch) // Close the channel to stop range loop</code>
이렇게 하면 채널에 충분한 공간이 확보되고 명시적으로 닫혀 범위 루프가 종료될 수 있습니다.
해결책 2: 고루틴의 완료 조건 신호
<code class="go">func main() { ch := make(chan []int, 4) var m []int var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func() { ch <- m wg.Done() // Signal completion within goroutine return }() } go func() { for c := range ch { fmt.Printf("c is %v\n", c) wg.Done() //Decrement count for each iteration } }() wg.Wait() }</code>
이 솔루션에서 각 고루틴은 고루틴 자체 내에서 wg.Done()을 호출하여 완료를 알립니다. 또한 대기 그룹은 각 반복마다 범위 루프 내에서 감소하여 wg.Wait()가 결국 완료되고 프로그램이 종료되도록 합니다.
위 내용은 Go에서 WaitGroups 및 버퍼링된 채널을 사용할 때 교착 상태가 어떻게 발생할 수 있나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!