我正在学习Go,并且正在使用Goroutine和频道。我当时使用两个缓冲通道(一个用于输入,一个用于输出)编写了一个非常人性化的天真工作池。
现在,我在向其添加作业之后关闭了输入通道,然后最终读取了输出通道以从中读取结果,但是,当我使用let convertedDate;
if (isNaN(myDate)) {
convertedDate = moment(myDate,'MMM/dd/yyyy').format('YYYYDDMMHHmmss');
} else {
convertedDate = myDate; // already in YYYYDDMMHHmmss format like date1
}
导致输出程序出现死锁时会出现恐慌。这是示例代码
for val := range ch
这是我看到的输出
package main
import (
"fmt"
"time"
)
func main() {
st := time.Now()
jobs := make(chan int, 100)
res := make(chan int, 100)
// Putting items to the jobs channel
for i := 0; i < 9; i++ {
jobs <- i
}
close(jobs)
go workerPool(jobs, res, 1)
// This causes the program to panic with deadlock
for v := range res {
fmt.Println(v)
}
// This works just fine and program does not panics
//for i := 0; i < 9; i++ {
// fmt.Println(<-res)
//}
ed := time.Now()
fmt.Println(ed.Sub(st))
}
func workerPool(ip <-chan int, op chan<- int, id int) {
for v := range ip {
fmt.Println("Worker", id, "working on ", v)
op <- 1
}
}
我了解到,当我使用常规的Worker 1 working on 0
Worker 1 working on 1
Worker 1 working on 2
Worker 1 working on 3
Worker 1 working on 4
Worker 1 working on 5
Worker 1 working on 6
Worker 1 working on 7
Worker 1 working on 8
1
1
1
1
1
1
1
1
1
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
main.main()
时,我正在获取最初放入for loop
通道中的值的准确数量(9)。但是jobs
是否应该自动处理此问题,即当没有更多数据要从通道读取时,通道将发送for range
值并且循环将终止?
答案 0 :(得分:0)
解决方案非常明显,我要做的就是close
工作者中的输出通道,并且range
由于明显的原因而开始正常工作。
func workerPool(ip <-chan int, op chan<- int, id int) {
for v := range ip {
fmt.Println("Worker", id, "working on ", v)
op <- fib(v)
}
close(op) // change made
}