"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > GoLang에서 버퍼링된 채널을 통해 범위를 지정할 때 교착 상태를 피하는 방법은 무엇입니까?

GoLang에서 버퍼링된 채널을 통해 범위를 지정할 때 교착 상태를 피하는 방법은 무엇입니까?

2024-11-02에 게시됨
검색:474

How to Avoid Deadlock When Ranging Over a Buffered Channel in GoLang?

GoLang의 교착 상태: 왜 버퍼링된 채널을 통해 범위를 지정해야 합니까?

GoLang에서 버퍼링된 채널을 사용할 때 교착 상태를 피하는 것이 중요합니다. . 최근 문제로 인해 모든 고루틴이 완료된 후 버퍼링된 채널을 통해 범위를 지정하려고 시도하는 동안 발생하는 교착 상태에 대한 우려가 제기되었습니다.

제공된 코드는 용량이 4인 버퍼링된 채널을 사용하고 데이터를 보내는 4개의 고루틴을 생성하려고 시도합니다. 채널에. 그러나 다음과 같은 이유로 교착 상태가 발생합니다.

  • 채널 크기가 너무 작아서 차단된 고루틴이 전체 채널에 쓰기를 기다리고 있습니다.
  • 채널의 작업 범위는 무기한으로 유지됩니다. 쓸 고루틴이 남아 있지 않은 동안 요소가 도착하기를 기다리고 있습니다.

해결책 1: 채널 크기를 확장하고 완료 후 닫기

교착 상태를 해결하려면, 모든 고루틴이 완료된 후 채널의 크기를 늘리고 닫을 수 있습니다:

ch := make(chan []int, 5)
...
wg.Wait()
close(ch)

그러나 이는 모든 작업이 완료될 때까지 인쇄를 방지하므로 파이프라이닝의 이점을 제거합니다.

해결책 2: 인쇄 루틴 내에서 신호 완료

실제 파이프라이닝을 활성화하려면 인쇄 루틴 내에서 Done() 함수를 호출할 수 있습니다.

func main() {
    ch := make(chan []int, 4)
    ...
    go func() {
        for c := range ch {
            fmt.Printf("c is %v\n", c)
            wg.Done()
        }
    }()
    ...
}

이 접근 방식은 각 요소가 인쇄된 후에만 Done() 함수가 호출되어 각 고루틴의 완료를 효과적으로 알립니다.

최신 튜토리얼 더>

부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.

Copyright© 2022 湘ICP备2022001581号-3