관용적인 고루틴 종료 및 오류 처리: 사례 연구
Go에서 고루틴 종료를 처리하는 것은 종종 개발자에게 어려운 일입니다. 일반적인 문제 중 하나는 오류가 발생할 때 고루틴을 적절하게 정리하는 것입니다. 이 문서에서는 오류 그룹화를 사용하여 이 문제에 대한 우아하고 관용적인 솔루션을 보여줍니다.
다음 예를 고려하세요.
package main import ( "sync" "time" ) func fetchAll() error { wg := sync.WaitGroup{} errs := make(chan error) // run all the http requests in parallel for i := 0; i < 4; i++ { wg.Add(1) go func(i int) { defer wg.Done() // pretend this does an http request and returns an error time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond) errs <- fmt.Errorf("goroutine %d's error returned", i) }(i) } // wait until all the fetches are done and close the error // channel so the loop below terminates go func() { wg.Wait() close(errs) }() // return the first error for err := range errs { if err != nil { return err } } return nil }
이 구현에는 치명적인 결함이 있습니다. 즉, 고루틴이 누출됩니다. 해결 방법은 오류 그룹을 사용하는 것입니다.
package main import ( "context" "fmt" "math/rand" "time" "golang.org/x/sync/errgroup" ) func fetchAll(ctx context.Context) error { errs, ctx := errgroup.WithContext(ctx) // run all the http requests in parallel for i := 0; i < 4; i++ { errs.Go(func() error { // pretend this does an http request and returns an error time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond) return fmt.Errorf("error in go routine, bailing") }) } // Wait for completion and return the first error (if any) return errs.Wait() }
오류 그룹은 모든 고루틴이 성공적으로 완료될 때까지 자동으로 기다리거나 오류가 발생할 경우 남은 고루틴을 취소합니다. 위의 경우 오류가 발생한 첫 번째 고루틴은 다른 모든 고루틴을 취소하고 오류는 호출자에게 다시 전파됩니다. 컨텍스트를 사용하면 주변 컨텍스트가 취소될 때 우아한 종료가 보장됩니다.
위 내용은 Go에서 고루틴을 정상적으로 종료하고 오류를 처리하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!