목차
질문 내용
해결책
더 나은 방법: 선택을 위해 nil가능한 채널을 사용
백엔드 개발 Golang 세 번째 고루틴 내에서 두 고루틴의 완료 상태를 추적하기 위한 Golang의 모범 사례는 무엇입니까?

세 번째 고루틴 내에서 두 고루틴의 완료 상태를 추적하기 위한 Golang의 모범 사례는 무엇입니까?

Feb 11, 2024 pm 02:54 PM
overflow

Golang 中跟踪第三个 Goroutine 中两个 Goroutine 的完成状态的最佳实践是什么?

세 번째 고루틴에서 두 고루틴의 완료 상태를 추적하기 위한 Golang의 모범 사례는 무엇입니까? Golang에서 두 고루틴의 완료 상태를 추적하고 그 결과를 세 번째 고루틴에서 처리하려면 동기화 패키지에서 WaitGroup을 사용하는 것이 가장 좋습니다. WaitGroup을 사용하면 다른 고루틴이 완료될 때까지 기본 고루틴에서 기다릴 수 있습니다. 먼저, WaitGroup 개체를 생성하고 기본 고루틴에서 Add 메서드를 호출하여 대기 중인 고루틴 수를 설정해야 합니다. 그런 다음 각 고루틴이 끝날 때 Done 메서드가 호출되어 해당 고루틴의 완료를 알립니다. 마지막으로 세 번째 고루틴에서는 Wait 메소드가 호출되어 모든 고루틴이 완료될 때까지 기다립니다. 이런 방식으로 우리는 두 고루틴의 결과를 안전하게 추적하고 처리할 수 있습니다. 이는 여러 고루틴의 완료 상태를 추적하기 위한 Golang의 모범 사례입니다.

질문 내용

3개의 고루틴이 동시에 실행되고 있습니다. 그 중 두 개는 처리를 수행하고 결과를 결과 채널로 보냅니다. 세 번째 고루틴은 결과 채널을 읽어 결과를 "계산"합니다. 대기 그룹을 사용하여 두 계산 고루틴이 완료될 때까지 기다린 다음 결과 채널을 반복하여 결과를 계산할 수 있지만 이는 확장되지 않으며 엄청난 버퍼 크기로 버퍼링된 결과 채널을 만들어야 하는데 이는 허용되지 않습니다. 프로덕션 코드에서.

처리가 진행되는 동안 결과를 계산하고 싶지만 모든 계산이 완료되기 전에 프로그램을 종료하고 싶지 않습니다. Go에서 이를 달성하기 위한 모범 사례는 무엇입니까?

이것이 현재 제가 사용하는 방법이며 훌륭하게 작동합니다. 조금 투박해 보이는데 더 좋은 방법이 있는지 궁금합니다.

package main

import (
    "fmt"
    "sync"
)

type T struct{}

func main() {
    var widgetInventory int = 1000
    transactions := make(chan int, 100)
    salesDone := make(chan T)
    purchasesDone := make(chan T)
    var wg sync.WaitGroup
    fmt.Println("Starting inventory count = ", widgetInventory)

    go makeSales(transactions, salesDone)
    go newPurchases(transactions, purchasesDone)

    wg.Add(1)

    go func() {
        salesAreDone := false
        purchasesAreDone := false

        for {
            select {
            case transaction := <-transactions:
                widgetInventory += transaction
            case <-salesDone:
                salesAreDone = true
            case <-purchasesDone:
                purchasesAreDone = true
            default:
                if salesAreDone && purchasesAreDone {
                    wg.Done()
                    return
                }
            }
        }
    }()

    wg.Wait()
    fmt.Println("Ending inventory count = ", widgetInventory)
}

func makeSales(transactions chan int, salesDone chan T) {
    for i := 0; i < 3000; i++ {
        transactions <- -100
    }

    salesDone <- struct{}{}
}

func newPurchases(transactions chan int, purchasesDone chan T) {
    for i := 0; i < 3000; i++ {
        transactions <- 100
    }

    purchasesDone <- struct{}{}
}
로그인 후 복사

해결책

은 어떤 합리적인 정의괜찮아에 맞지 않습니다. 여기에 인기 있는 for 루프가 있습니다:

으아악

읽을 채널이 없으면 default사건이 실행됩니다. 채널이 작동하는 방식 때문에 이런 일이 많이 발생합니다.

약간 수정된 코드 버전은 이 루프의 "열"을 보여줍니다. 정확한 결과는 다양하며 상당히 높을 수 있습니다.

으아악

기본값이 채널의 항목을 차단하지 않는 한 채널에서 선택할 때 selecting 来自通道时,您不希望出现 default 사례를 원하지 않습니다. 그렇지 않으면 이와 같은 열 순환이 발생합니다.

더 나은 방법: 선택을 위해 nil가능한 채널을 사용

일반적으로 선택 항목에서 닫힌 채널을 식별하고 채널 변수를 nilselect 永远不会成功地从 nil

로 설정하려는 경우 select

채널에서 성공적으로 읽히지 않으므로 선택 항목이 효과적으로 "비활성화"됩니다.

코드의 수정된 버전

을 고려해보세요: salesDonepurchasesDone 都被“发出信号”,我们 close(transactions)。一旦我们耗尽 transactions 并且它被关闭,我们将 transactions 设置为 nil。我们在 transactions 不为 nil 时循环,在这段代码中,意味着所有通道都是 nil 으아악

소비자에 대한 이러한 조정으로 더 이상 핫 루프가 없으며 채널에서 데이터를 읽을 때까지 항상 차단됩니다. salesDonepurchasesDone이 모두 "신호"되면 거래를 종료합니다. 트랜잭션을 소진하고

main 共享范围。否则,将 transactions 设置为 nil 将写入一个在 goroutine 之间共享的变量。然而在这种情况下,无论如何,这并不重要,因为我们“知道”我们是最后一个从 transactions 종료되면 트랜잭션을 nil로 설정합니다. transactions가 nil이 아닐 때 반복합니다. 이는 이 코드에서 모든 채널이

임을 의미합니다.

미묘하지만 중요한 점: 이 함수에 채널을 전달하므로 해당 참조가 main과 범위를 공유하지 않습니다. 그렇지 않은 경우 transactions

로 설정하면 고루틴 간에 공유되는 변수에 기록됩니다. 그러나 이 경우에는 우리가 트랜잭션에서 마지막으로 읽은 것임을 "알기" 때문에 어쨌든 문제가 되지 않습니다. transactions 的生产。然后你想排空 transactions。一旦通道关闭并排空,main

더 쉬운 옵션: 여러 대기 그룹

select 来执行此操作。而 select여기서 무엇을 하고 있는지 생각해보면 두 프로듀서가 페어링을 완료할 때까지 기다려야

합계가 완료되었다는 사실을 알기 전에 기다려야 합니다.

각 "작업자"에 대한 케이스를 🎜 가질 필요는 없습니다. 이는 꽤 우아하지 않은 일이지만, 여러 작업자를 하드코딩하고 "완료" 채널을 개별적으로 처리해야 합니다. 🎜 🎜당신이 해야 할 일은:🎜
  • 除了为生产者使用一个 var resultswgsync.WaitGroup 之外,还为消费者添加一个。
  • 生产者 defer wg.Done()
  • 消费者 defer resultswg.Done() 在遍历 transactions 之前:
    go func() {
        defer resultswg.Done()
        for transaction := range transactions {
            widgetInventory += transaction
        }
    }()
    로그인 후 복사
  • main 处理等待生产者、关闭事务以结束范围,然后等待消费者:
    wg.Wait()
    close(transactions)
    resultswg.Wait()
    로그인 후 복사

以这种方式编码,最终会变得简短而甜蜜

package main

import (
    "fmt"
    "sync"
)

func main() {
    var widgetInventory int = 1000
    transactions := make(chan int, 100)

    var wg, resultswg sync.WaitGroup
    fmt.Println("Starting inventory count = ", widgetInventory)
    wg.Add(2)

    go makeSales(transactions, &wg)
    go newPurchases(transactions, &wg)
    resultswg.Add(1)
    go func() {
        defer resultswg.Done()
        for transaction := range transactions {
            widgetInventory += transaction
        }
    }()

    wg.Wait()
    close(transactions)
    resultswg.Wait()
    fmt.Println("Ending inventory count = ", widgetInventory)
}

func makeSales(transactions chan int, wg *sync.WaitGroup) {
    defer wg.Done()
    for i := 0; i < 3000; i++ {
        transactions <- -100
    }

}

func newPurchases(transactions chan int, wg *sync.WaitGroup) {
    defer wg.Done()
    for i := 0; i < 3000; i++ {
        transactions <- 100
    }

}
로그인 후 복사

您可以在这里看到,在此模式中可以有任意数量的生产者;您只需为每个生产者添加 wg.Add(1) 即可。

当我不知道每个工作人员会返回多少结果时,我一直使用这种模式来并行化工作。我发现它很容易理解,并且比尝试 select 多个通道简单得多。事实上,我什至想说,如果您发现自己从多个渠道进行 selecting,您应该退后一步,确保它对您来说确实有意义。我使用 select 的频率远远低于使用等待组的频率。

위 내용은 세 번째 고루틴 내에서 두 고루틴의 완료 상태를 추적하기 위한 Golang의 모범 사례는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

2009-2025년 탄생 이후 비트코인 ​​가격 BTC 역사적 가격에 대한 가장 완벽한 요약 2009-2025년 탄생 이후 비트코인 ​​가격 BTC 역사적 가격에 대한 가장 완벽한 요약 Jan 15, 2025 pm 08:11 PM

2009년 창립 이래 비트코인은 암호화폐 세계의 리더가 되었으며 가격은 큰 변동을 겪었습니다. 포괄적인 역사적 개요를 제공하기 위해 이 기사에서는 2009년부터 2025년까지의 비트코인 ​​가격 데이터를 수집하여 주요 시장 이벤트, 시장 정서 변화, 가격 변동에 영향을 미치는 중요한 요소를 다룹니다.

비트코인 탄생 이후의 역사적 가격 개요 비트코인의 역사적 가격 추세를 완벽하게 수집합니다. 비트코인 탄생 이후의 역사적 가격 개요 비트코인의 역사적 가격 추세를 완벽하게 수집합니다. Jan 15, 2025 pm 08:14 PM

암호화폐인 비트코인은 출시 이후 상당한 시장 변동성을 경험해 왔습니다. 이 기사에서는 독자들이 가격 추세와 주요 순간을 이해하는 데 도움이 되도록 탄생 이후 비트코인의 역사적 가격에 대한 개요를 제공합니다. 비트코인의 과거 가격 데이터를 분석함으로써 우리는 시장의 가치 평가, 변동에 영향을 미치는 요인을 이해하고 향후 투자 결정의 기초를 제공할 수 있습니다.

비트 코인 BTC 역사 가격 추세 차트의 탄생 이후의 역사적 가격 목록 (최신 요약) 비트 코인 BTC 역사 가격 추세 차트의 탄생 이후의 역사적 가격 목록 (최신 요약) Feb 11, 2025 pm 11:36 PM

Bitcoin의 Price는 2009 년에 창설 된 이래 2021 년 11 월에 69,044.77 달러로 상승하여 2018 년 12 월에 3,191.22 달러로 감소했습니다. 2024 년 12 월 현재 최신 가격은 $ 100,204를 초과했습니다.

2018-2024 USD의 Bitcoin의 최신 가격 2018-2024 USD의 Bitcoin의 최신 가격 Feb 15, 2025 pm 07:12 PM

실시간 비트 코인 USD 가격 비트 코인 가격에 영향을 미치는 요인 향후 비트 코인 가격을 예측하기위한 지표 다음은 2018-2024 년 비트 코인 가격에 대한 몇 가지 주요 정보입니다.

비트 코인이 탄생 한 이후의 역사 가격 세부 사항에 대한 가장 완전한 요약 (2025 년 최신 버전) 비트 코인이 탄생 한 이후의 역사 가격 세부 사항에 대한 가장 완전한 요약 (2025 년 최신 버전) Feb 15, 2025 pm 06:45 PM

비트 코인 역사 가격에 대한 중요한 노드 2009 년 1 월 3 일 : 창세기 블록이 생성되었고, 첫 번째 비트 코인이 생성되었으며, 값이 0입니다. 10 월 5 일 : 최초의 비트 코인 거래 인 프로그래머는 10,000 비트 코인이있는 피자 2 개를 $ 0.008에 해당했습니다. 2010 년 2 월 9 일 : Mt. Gox Exchange는 온라인으로 가서 초기 비트 코인 거래의 주요 플랫폼이되었습니다. 5 월 22 일 : 비트 코인은 처음으로 $ 1을 뚫고 나옵니다. 7 월 17 일 : 비트 코인 가격은 $ 0.008로 급락하여 사상 최저치를 기록했습니다. 2011 년 2 월 9 일 : 비트 코인 가격은 처음으로 10 달러를 겪습니다. 4 월 10 일 : Mt. Go

Chatgpt 시대에는 기술 Q & A 커뮤니티가 어떻게 도전에 대응할 수 있습니까? Chatgpt 시대에는 기술 Q & A 커뮤니티가 어떻게 도전에 대응할 수 있습니까? Apr 01, 2025 pm 11:51 PM

Chatgpt 시대의 기술 Q & A 커뮤니티 : Segmentfault의 응답 전략 stackoverflow ...

한 기사에서 : 가상 통화 펀드 요금은 무엇이며 자금 요금을 사용하여 거래하는 방법 한 기사에서 : 가상 통화 펀드 요금은 무엇이며 자금 요금을 사용하여 거래하는 방법 Feb 15, 2025 pm 10:06 PM

가상 통화 자금 조달 요율은 파생 상품 거래에서 직책을 보유한 거래자에게 청구되는 수수료입니다. 계약이 만료 될 때 현물 시장 가격과 선물 계약 가격 간의 보험료 또는 할인을 반영합니다. 스팟 가격이 선물 가격보다 높으면 자본 비율은 마이너스이므로, 짧은 포지션을하는 거래자는 오랜 지위를 가진 거래자에게 수수료를 지불합니다. 반대로, 스팟 가격이 선물 가격보다 낮을 때, 자본 비율은 긍정적이므로, 이는 장거리 포지션을하는 거래자가 짧은 포지션을하는 거래자에게 수수료를 지불한다는 것을 의미합니다.

CSS의 클립 경로 속성을 사용하여 세그먼터의 45도 곡선 효과를 달성하는 방법은 무엇입니까? CSS의 클립 경로 속성을 사용하여 세그먼터의 45도 곡선 효과를 달성하는 방법은 무엇입니까? Apr 04, 2025 pm 11:45 PM

세그먼터의 45도 곡선 효과를 달성하는 방법은 무엇입니까? 세분화 장치를 구현하는 과정에서 왼쪽 버튼을 클릭 할 때 오른쪽 테두리를 45도 곡선으로 바꾸는 방법과 포인트 ...

See all articles