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

Noluye ·
有一点一直绕不过来弯,jobs与results的容量都是10,最后怎么能打印出来一百条数据的,超过10条不就应该死锁了吗
#18
更多评论
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](https://www.amazon.com/dp/0134190440/?tag=stackoverflow17-20)》的说法: > 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