고루틴 교착 상태 해결
동시 Golang 프로그램으로 작업할 때 교착 상태 오류가 발생할 수 있습니다: "치명적인 오류: 모든 고루틴이 잠자기 상태입니다 - 이중 자물쇠!". 이 오류는 여러 고루틴이 작업을 수행하기 위해 서로 대기하여 교착 상태 상황이 발생할 때 발생합니다.
다음 코드를 고려하세요.
<code class="go">func producer(ch chan int, d time.Duration, num int) { for i := 0; i < num; i++ { ch <- i time.Sleep(d) } } func main() { ch := make(chan int) go producer(ch, 100*time.Millisecond, 2) go producer(ch, 200*time.Millisecond, 5) for { fmt.Println(<-ch) } close(ch) }</code>
이 코드는 값을 보내는 두 개의 생산자 고루틴을 생성합니다. 같은 채널로. 메인 고루틴은 무한 루프를 통해 지속적으로 채널로부터 값을 받습니다.
생산자가 "단명"하고 유한한 시간이 지나면 값 전송을 중지하지만 메인 고루틴은 계속해서 값을 받기 때문에 문제가 발생합니다. 끝없이. 더 이상 값이 전송되지 않는다는 신호를 보내기 위해 채널이 닫히지 않기 때문에 이로 인해 교착 상태가 발생합니다.
이 교착 상태를 해결하려면 모든 생산자가 작업을 완료했을 때 채널이 닫히도록 해야 합니다. 이를 달성하는 효율적인 방법은 sync.WaitGroup과 같은 동기화 기본 요소를 사용하는 것입니다.
수정된 코드 버전은 다음과 같습니다.
<code class="go">func producer(ch chan int, d time.Duration, num int, wg *sync.WaitGroup) { defer wg.Done() for i := 0; i < num; i++ { ch <- i time.Sleep(d) } } func main() { wg := &sync.WaitGroup{} ch := make(chan int) wg.Add(1) go producer(ch, 100*time.Millisecond, 2, wg) wg.Add(1) go producer(ch, 200*time.Millisecond, 5, wg) go func() { wg.Wait() close(ch) }() for v := range ch { fmt.Println(v) } }</code>
이 코드에서는 동기화를 전달합니다. 각 생산자 고루틴에 대한 WaitGroup입니다. 각 생산자는 시작하기 전에 대기 그룹을 늘리고 완료되면 줄입니다. 기본 고루틴은 wg.Wait()를 사용하여 모든 생산자가 완료될 때까지 기다립니다. 모든 프로듀서가 작업을 마치면 메인 고루틴이 채널을 닫습니다.
이 솔루션은 모든 프로듀서가 작업을 완료한 후에만 채널을 닫아 교착 상태를 방지합니다.
위 내용은 고루틴과 채널을 사용할 때 Golang에서 교착 상태를 방지하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!