>백엔드 개발 >Golang >Go에서 WaitGroups 및 버퍼링된 채널을 사용할 때 교착 상태를 방지하려면 어떻게 해야 합니까?

Go에서 WaitGroups 및 버퍼링된 채널을 사용할 때 교착 상태를 방지하려면 어떻게 해야 합니까?

Linda Hamilton
Linda Hamilton원래의
2024-10-26 18:10:02389검색

How can I prevent deadlock when using WaitGroups and buffered channels in Go?

Go의 교착 상태: WaitGroup 및 버퍼 채널

Go에서는 동시 goroutine이 서로 완료될 때까지 무기한 기다릴 때 교착 상태가 발생합니다. 교착 상태의 일반적인 원인 중 하나는 WaitGroups 및 버퍼링된 채널의 사용과 관련이 있습니다.

교착 상태의 예

다음 코드를 고려하세요.

<code class="go">package main

import "fmt"
import "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 // Sending to a full channel
            return
        }()
    }
    wg.Wait()

    for c := range ch {
        fmt.Printf("c is %v", c)
    }
}</code>

이 코드는 5개의 빈 슬라이스를 용량이 4인 버퍼링된 채널로 보낸 다음 모든 고루틴이 완료된 후 채널에서 읽습니다. 그러나 코드에서 교착 상태 오류가 발생합니다.

교착 상태의 원인

두 가지 문제로 인해 교착 상태가 발생합니다.

  1. 채널 버퍼 부족: 채널의 용량은 4개로 데이터를 전송하려는 5개의 고루틴에 비해 너무 작습니다. 채널이 가득 차면 데이터 전송을 기다리는 후속 고루틴(라인 15)이 무기한 차단됩니다.
  2. 채널 반복 차단: 채널(라인 22-24)을 반복하는 루프가 차단됩니다. 더 많은 요소가 채널에 도착할 때까지 기다리기 때문입니다. 모든 고루틴이 데이터 전송을 마쳤고 더 이상 데이터가 예상되지 않으므로 채널에서 해당 고루틴을 읽지 않으면 이 반복이 완료되지 않습니다.

해결책

교착 상태를 해결하려면 다음 수정 중 하나를 수행하십시오.

해결책 1:

채널 용량을 5(또는 그 이상)로 늘리고 모든 데이터를 보낸 후 닫습니다. :

<code class="go">ch := make(chan []int, 5)
...
wg.Wait()
close(ch)</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()
        }()
    }
    go func() {
        for c := range ch {
            fmt.Printf("c is %v\n", c)
            wg.Done()
        }
    }()
    wg.Wait()
}</code>

위 내용은 Go에서 WaitGroups 및 버퍼링된 채널을 사용할 때 교착 상태를 방지하려면 어떻게 해야 합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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