gpt4 book ai didi

go - 为什么此goroutine不调用wg.Done()?

转载 作者:行者123 更新时间:2023-12-01 22:08:52 24 4
gpt4 key购买 nike

假设任何时候在registerChan上最多有两个元素(工作人员地址)。然后由于某种原因,以下代码不会在最后两个goroutines中调用wg.Done()。

func schedule(jobName string, mapFiles []string, nReduce int, phase jobPhase, registerChan chan string) {
var ntasks int
var nOther int // number of inputs (for reduce) or outputs (for map)
switch phase {
case mapPhase:
ntasks = len(mapFiles)
nOther = nReduce
case reducePhase:
ntasks = nReduce
nOther = len(mapFiles)
}

fmt.Printf("Schedule: %v %v tasks (%d I/Os)\n", ntasks, phase, nOther)

const rpcname = "Worker.DoTask"
var wg sync.WaitGroup
for taskNumber := 0; taskNumber < ntasks; taskNumber++ {
file := mapFiles[taskNumber%len(mapFiles)]
taskArgs := DoTaskArgs{jobName, file, phase, taskNumber, nOther}
wg.Add(1)
go func(taskArgs DoTaskArgs) {
workerAddr := <-registerChan
print("hello\n")
// _ = call(workerAddr, rpcname, taskArgs, nil)
registerChan <- workerAddr
wg.Done()
}(taskArgs)
}
wg.Wait()
fmt.Printf("Schedule: %v done\n", phase)
}

如果我把 wg.Done()放在 registerChan <- workerAddr之前,那很好,我也不知道为什么。我也尝试过推迟wg.Done(),但是即使我希望这样做也似乎不起作用。我想我对例程和 channel 的运行方式有一些误解,这使我感到困惑。

最佳答案

因为它在这里停止了:

workerAddr := <-registerChan

对于缓冲 channel :
要使此 workerAddr := <-registerChan起作用: channel registerChan必须具有一个值;否则, 代码将在此处停止,以等待 channel 。

我设法以这种方式运行您的代码(尝试 this):
package main

import (
"fmt"
"sync"
)

func main() {
registerChan := make(chan int, 1)
for i := 1; i <= 10; i++ {
wg.Add(1)
go fn(i, registerChan)
}
registerChan <- 0 // seed
wg.Wait()
fmt.Println(<-registerChan)
}

func fn(taskArgs int, registerChan chan int) {
workerAddr := <-registerChan
workerAddr += taskArgs
registerChan <- workerAddr
wg.Done()
}

var wg sync.WaitGroup


输出:
55

解释:
此代码使用一个 channel 将1到10加到10个goroutines加一个main goroutine。

我希望这有帮助。

关于go - 为什么此goroutine不调用wg.Done()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58743038/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com