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

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

Linda Hamilton
Linda Hamilton원래의
2024-10-26 17:51:02231검색

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

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

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

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

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

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

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

<code class="go">ch := make(chan []int, 5)
...
wg.Wait()
close(ch)</code>

그러나 이렇게 하면 모든 작업이 완료될 때까지 인쇄가 방지되므로 파이프라이닝의 이점이 사라집니다.

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

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

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

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

위 내용은 GoLang에서 버퍼링된 채널을 통해 범위를 지정할 때 교착 상태를 피하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.