【发布时间】:2021-12-03 02:28:47
【问题描述】:
在下面的代码中,我不明白为什么“Worker”方法似乎退出而不是从“in”输入通道中提取值并处理它们。
我曾假设它们只会在消耗来自输入通道“in”的所有输入并处理它们之后才会返回
package main
import (
"fmt"
"sync"
)
type ParallelCallback func(chan int, chan Result, int, *sync.WaitGroup)
type Result struct {
i int
val int
}
func Worker(in chan int, out chan Result, id int, wg *sync.WaitGroup) {
for item := range in {
item *= item // returns the square of the input value
fmt.Printf("=> %d: %d\n", id, item)
out <- Result{item, id}
}
wg.Done()
fmt.Printf("%d exiting ", id)
}
func Run_parallel(n_workers int, in chan int, out chan Result, Worker ParallelCallback) {
wg := sync.WaitGroup{}
for id := 0; id < n_workers; id++ {
fmt.Printf("Starting : %d\n", id)
wg.Add(1)
go Worker(in, out, id, &wg)
}
wg.Wait() // wait for all workers to complete their tasks
close(out) // close the output channel when all tasks are completed
}
const (
NW = 4
)
func main() {
in := make(chan int)
out := make(chan Result)
go func() {
for i := 0; i < 100; i++ {
in <- i
}
close(in)
}()
Run_parallel(NW, in, out, Worker)
for item := range out {
fmt.Printf("From out : %d: %d", item.i, item.val)
}
}
输出是
Starting : 0
Starting : 1
Starting : 2
Starting : 3
=> 3: 0
=> 0: 1
=> 1: 4
=> 2: 9
fatal error: all goroutines are asleep - deadlock!
【问题讨论】:
-
在
in关闭之前,工人无法返回。你认为他们为什么会提前回来? -
这基本上是同一个问题
-
对不起,我不明白。你说“他们似乎退出了”,但他们没有退出。发生了哪些您没有预料到的具体情况?
-
我可能错了,问题可能出在其他地方:我在代码之后添加了输出以响应您的评论。查看输出。
-
错误输出将显示所有 goroutine 被阻塞的位置。我假设您在
Run_parallel中被阻止,因为直到Run_parallel返回之后,您才从out消费。
标签: go worker-pool