세 번째 고루틴 내에서 두 고루틴의 완료 상태를 추적하기 위한 Golang의 모범 사례는 무엇입니까?
세 번째 고루틴에서 두 고루틴의 완료 상태를 추적하기 위한 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
사건이 실행됩니다. 채널이 작동하는 방식 때문에 이런 일이 많이 발생합니다.
약간 수정된 코드 버전은 이 루프의 "열"을 보여줍니다. 정확한 결과는 다양하며 상당히 높을 수 있습니다.
으아악기본값이 채널의 항목을 차단하지 않는 한 채널에서 선택
할 때 select
ing 来自通道时,您不希望出现 default
사례를 원하지 않습니다. 그렇지 않으면 이와 같은 열 순환이 발생합니다.
더 나은 방법: 선택을 위해 nil
가능한 채널을 사용
일반적으로 선택 항목에서 닫힌 채널을 식별하고 채널 변수를 nil
; select
永远不会成功地从 nil
select
는 채널에서 성공적으로 읽히지 않으므로 선택 항목이 효과적으로 "비활성화"됩니다.
코드의 수정된 버전을 고려해보세요: salesDone
和 purchasesDone
都被“发出信号”,我们 close(transactions)
。一旦我们耗尽 transactions
并且它被关闭,我们将 transactions
设置为 nil。我们在 transactions
不为 nil 时循环,在这段代码中,意味着所有通道都是 nil
으아악
salesDone
과 purchasesDone
이 모두 "신호"되면 거래를 종료
합니다. 트랜잭션
을 소진하고 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
多个通道简单得多。事实上,我什至想说,如果您发现自己从多个渠道进行 select
ing,您应该退后一步,确保它对您来说确实有意义。我使用 select
的频率远远低于使用等待组的频率。
위 내용은 세 번째 고루틴 내에서 두 고루틴의 완료 상태를 추적하기 위한 Golang의 모범 사례는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

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

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

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

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

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

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

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

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

뜨거운 주제









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

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

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

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

비트 코인 역사 가격에 대한 중요한 노드 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 커뮤니티 : Segmentfault의 응답 전략 stackoverflow ...

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

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