>  기사  >  백엔드 개발  >  Go에서 외부 함수와 함께 sync.WaitGroup을 사용할 때 교착 상태를 방지하는 방법은 무엇입니까?

Go에서 외부 함수와 함께 sync.WaitGroup을 사용할 때 교착 상태를 방지하는 방법은 무엇입니까?

Mary-Kate Olsen
Mary-Kate Olsen원래의
2024-11-05 22:03:02877검색

How to Avoid Deadlocks When Using sync.WaitGroup with External Functions in Go?

외부 함수와 sync.WaitGroup 활용 모범 사례

Go에서 동시성을 처리하려면 sync.WaitGroup을 효과적으로 활용하는 것이 중요합니다. 이 문서에서는 대기 그룹을 외부 함수에 대한 인수로 전달할 때 발생하는 일반적인 문제를 다룹니다.

문제:

다음 코드를 고려하세요.

<code class="go">package main

import (
    "fmt"
    "sync"
)

func main() {
    ch := make(chan int)
    var wg sync.WaitGroup
    wg.Add(2)
    go Print(ch, wg) //
    go func(){

        for i := 1; i <= 11; i++ {
            ch <- i
        }

        close(ch)
        defer wg.Done()


    }()

    wg.Wait() //deadlock here
}

// Print prints all numbers sent on the channel.
// The function returns when the channel is closed.
func Print(ch <-chan int, wg sync.WaitGroup) {
    for n := range ch { // reads from channel until it's closed
        fmt.Println(n)
    }
    defer wg.Done()
}</code>

이 코드에서는 지정된 줄에서 교착 상태가 발생하여 프로그램이 11에 도달하지 않고 1부터 10까지만 인쇄하게 됩니다. 이 오류는 sync.WaitGroup의 복사본을 Print 메서드에 전달하는 데서 발생합니다. Done 메서드에 대한 예상 호출.

해결책 1:

이 문제를 해결하려면 대신 대기 그룹에 포인터를 전달하세요.

<code class="go">package main

import (
    "fmt"
    "sync"
)

func main() {    
    ch := make(chan int)

    var wg sync.WaitGroup
    wg.Add(2)    

    go Print(ch, &wg)

    go func() {  
        for i := 1; i <= 11; i++ {
            ch <- i
        }
        close(ch)
        defer wg.Done()
    }()          

    wg.Wait() //deadlock here
}                

func Print(ch <-chan int, wg *sync.WaitGroup) {
    for n := range ch { // reads from channel until it's closed
        fmt.Println(n)
    }            
    defer wg.Done()
}</code>

wg의 주소를 전달하면 Print 메서드가 주 함수에서 대기 중인 대기 그룹에 대해 Done 메서드를 호출하게 됩니다.

해결책 2: 단순화된 인쇄 방법

또는 대기 작업에 대한 지식이 필요하지 않으므로 Print 메서드를 WaitGroup 인수를 제거하여 단순화할 수 있습니다.

<code class="go">package main

import (
    "fmt"
)

func main() {    
    ch := make(chan int)
    go func() {  
        for i := 1; i <= 11; i++ {
            ch <- i
        }
        close(ch)
    }()          

    for n := range ch { // reads from channel until it's closed
        fmt.Println(n)
    }            
}                </code>

이 시나리오에서는 기본 고루틴이 채널을 직접 수신하여 인쇄합니다. 대기 그룹을 포함하지 않고 해당 값을 사용합니다. 이 접근 방식은 원하는 기능을 유지하고 Print 메서드 내에서 WaitGroup 관리가 필요하지 않게 합니다.

결론:

sync.WaitGroup을 외부 함수에 인수로 전달할 때, 함수가 기다리고 있는 대기 그룹에 대한 올바른 참조를 수신하는지 확인하는 것이 중요합니다. 대기 그룹을 직접 처리하거나 대기 그룹에 포인터를 전달하도록 함수를 리팩토링하면 교착 상태 오류를 효과적으로 방지하고 적절한 동시성 제어를 보장할 수 있습니다.

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

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