고루틴에서 결과를 수집할 때 교착 상태를 피하는 방법은 무엇입니까?

Patricia Arquette
풀어 주다: 2024-11-06 14:22:02
원래의
649명이 탐색했습니다.

How to Avoid Deadlocks When Gathering Results from Goroutines?

데이터 처리를 위해 고루틴 사용

Go에서 고루틴은 작업의 동시 실행을 가능하게 하는 경량 스레드입니다. 고루틴으로 작업할 때 교착 상태를 방지하려면 처리 후 결과를 적절하게 수집하는 것이 중요합니다.

문제 설명

다음 코드 조각을 고려하세요.

sampleChan := make(chan sample)
var wg sync.WaitGroup

// Read from contents list
for i, line := range contents {
    wg.Add(1)
    // Process each item with a goroutine and send output to sampleChan
    go newSample(line, *replicatePtr, *timePtr, sampleChan, &wg)
}
wg.Wait()

// Read from sampleChan and put into a slice
var sampleList []sample
for s := range sampleChan {
    sampleList = append(sampleList, s)
}
close(sampleChan)
로그인 후 복사

이 코드는 고루틴을 사용하여 목록의 항목을 처리하고 결과를 슬라이스로 수집하려고 시도합니다. 그러나 결과가 수집되기 전에 채널이 닫히기 때문에 교착 상태 오류가 발생합니다.

해결 방법

이 문제를 해결하려면 결국 비동기적으로 채널을 닫을 수 있습니다. 작업자가 처리를 완료했습니다. 수정된 코드는 다음과 같습니다.

for i, line := range contents {
    wg.Add(1)
    // Process each item with a goroutine and send output to sampleChan
    go newSample(line, *replicatePtr, *timePtr, sampleChan, &wg)
}

go func() {
    wg.Wait()
    close(sampleChan)
}()

for s := range sampleChan {
  ..
}
로그인 후 복사

이 코드는 항목을 처리하고 결과를 SampleChan으로 보내는 고루틴을 시작합니다. 동시에 모든 작업자가 완료될 때까지 기다린 다음 채널을 닫는 또 다른 고루틴도 시작합니다. 이렇게 하면 채널이 닫히기 전에 모든 결과가 수집됩니다.

대체 솔루션

코드 가독성과 테스트 가능성을 높이려면 동기식 newSample 함수와 핸들을 사용하는 것이 좋습니다.

for i, line := range contents {
    wg.Add(1)
    go func(line string) {
        defer wg.Done()
        sampleChan <- newSample(line, *replicatePtr, *timePtr)
    }(line)
}
로그인 후 복사

이 접근 방식은 동시성 기본 요소를 현지화하여 코드 유지 관리를 단순화하고 오류 위험을 줄입니다.

위 내용은 고루틴에서 결과를 수집할 때 교착 상태를 피하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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