> 백엔드 개발 > Golang > sync.WaitGroup을 사용할 때 Go 채널에서 교착 상태 오류를 수정하는 방법은 무엇입니까?

sync.WaitGroup을 사용할 때 Go 채널에서 교착 상태 오류를 수정하는 방법은 무엇입니까?

Patricia Arquette
풀어 주다: 2024-10-29 02:36:02
원래의
469명이 탐색했습니다.

How to Fix Deadlock Errors in Go Channels When Using sync.WaitGroup?

Go 채널의 교착 상태 오류 이해

이 기사에서는 "교착 상태"의 원인을 분석해 보겠습니다. 다음 코드 조각에서 Go 채널과 관련된 교착 상태 상황에서 발생하는 오류:

package main

import (
    "fmt"
    "sync"
)

func push(c chan int, wg sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        c <- i
    }
    wg.Done()
}

func pull(c chan int, wg sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        result, ok := <-c
        fmt.Println(result, ok)
    }
    wg.Done()
}

func main() {
    var wg sync.WaitGroup
    wg.Add(2)
    c := make(chan int)

    go push(c, wg)
    go pull(c, wg)

    wg.Wait()
}
로그인 후 복사

이 코드를 실행할 때 다음 오류가 발생합니다.

throw: all goroutines are asleep - deadlock!
로그인 후 복사

교착 상태 이해

이 코드의 sync.WaitGroup과 같은 구조체가 참조가 아닌 값으로 전달되기 때문에 교착 상태가 발생합니다. 이는 WaitGroup을 함수(푸시 및 풀)에 전달할 때 실제로 원래 개체 대신 WaitGroup의 복사본을 전달한다는 의미입니다.

결과적으로 각 함수는 자체 복사본에서 작동합니다. WaitGroup의 것이며 wg.Done()을 호출하면 자신의 복사본이 감소합니다. 이는 기본 고루틴이 기다리고 있는 원래 WaitGroup을 업데이트하지 않으므로 교착 상태가 발생합니다.

교착 상태 수정

이 문제를 해결하려면 포인터를 전달해야 합니다. 값 대신 WaitGroup에 추가합니다. 이렇게 하면 푸시 및 풀 기능이 모두 WaitGroup의 동일한 인스턴스에서 작동하고 wg.Done()에 대한 호출이 원래 객체에 영향을 미치게 됩니다.

수정된 코드 버전은 다음과 같습니다.

package main

import (
    "fmt"
    "sync"
)

func push(c chan int, wg *sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        c <- i
    }
    wg.Done()
}

func pull(c chan int, wg *sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        result, ok := <-c
        fmt.Println(result, ok)
    }
    wg.Done()
}

func main() {
    var wg sync.WaitGroup
    wg.Add(2)
    c := make(chan int)

    go push(c, &wg)
    go pull(c, &wg)

    wg.Wait()
}
로그인 후 복사

이렇게 변경하면 이제 WaitGroup에 대한 포인터를 함수에 전달하여 둘 다 동일한 개체에서 작업하고 해당 상태를 올바르게 업데이트하도록 할 수 있습니다. 이를 통해 교착 상태 상황이 제거되고 프로그램이 오류 없이 실행될 수 있습니다.

위 내용은 sync.WaitGroup을 사용할 때 Go 채널에서 교착 상태 오류를 수정하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿