Go 系列教程 —— 23. 缓冲信道和工作池(Buffered Channels and Worker Pools)

Noluye · 2018-03-06 23:15:05

这个是用来等待消费者,也就是等待 go result 协程去完成任务以后才可以推出程序,否则可能出现提前退出的情况,也就是还没有消费完,go 主进程已经结束(守护进程)

createWorkerPool 里面的等待只是用来等待一些列子协程完成各自任务,完成任务并投放到results通道

#5
更多评论

func allocate(noOfJobs int) {
for i := 0; i < noOfJobs; i++ { randomno := rand.Intn(999) job := Job{i, randomno} jobs <- job } close(jobs) } 如果for循环结束后,jobs里面的数据worker还来不及取走,这时执行到close,会不会导致works取数据失败?或者取不到足额的任务? 谢谢!!

#1

这里 close 和关闭文件的概念不同。
golang 里的 close 只是用于通知信道的接收方,所有数据都已经发送完毕,信道没有真正关闭
若用 for range 接收数据时,对于关闭了的信道,会接收完剩下的有效数据,并退出循环。如果没有 close 提示数据发送完毕的话,for range 会接收完剩下所有有效数据后发生阻塞。
所以接收方 worker 是可以把 jobs 剩下的数据取走的。后面垃圾收集器会自动回收掉该信道的内存。

可以参见《the go programming language》的说法:
> You needn't close every channel when you've finished with it. It's only necessary to close a channel when it is important to tell the receiving goroutines that all data have been sent. A channel that the garbage collector determinies to be unreachable will have its resources reclaimed whether or not it is closed. (Don't confuse this with the close operation for open files. It is important to call the Close method on every file when you've finished with it.)

#2