외부 함수와 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!