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

Noluye ·
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
不会的,close相当于给这个chan掷了一个标志,forrange会自动把chan里的数据取完,如果不用forrange而是用<-chan的话取到的则是零值,并且会有个ok的bool返回
#3