以下是一本书的实例https://github.com/goinaction/code/blob/master/chapter2/sample/search/search.go
// Launch a goroutine to monitor when all the work is done.
go func() {
// Wait for everything to be processed.
waitGroup.Wait()
// Close the channel to signal to the Display
// function that we can exit the program.
close(results)
}()
// Start displaying results as they are available and
// return after the final result is displayed.
Display(results)
如果我将waitGroup.Wait()和close(结果)移出goroutine函数,程序将被阻止,因为通道中的结果尚未被读取,并且它阻止将其他更多结果写入通道后进入a “尺寸”。但如果我使用大尺寸缓冲通道:
results := make(chan *Result, 100)
程序恢复正常。似乎通道由于大小限制而被阻止,并且在使用之前无法写入更多。是否有无缓冲通道的大小限制?为什么它会将一些消息写入通道并稍微减少WaitGroup计数器,然后在那里阻塞它自己?
答案 0 :(得分:2)
根据定义,unbuffered channel没有缓冲区大小。如果有东西要读,则发送块。请go tour让自己熟悉。
上面的代码阻塞的原因是您正在等待WaitGroup计数器达到零。我假设这是在goroutines(你没有展示的那些)完成写入通道之后完成的。其中一个写道,但所有其他人都在阻止。 Display
应该从频道中读取(您也不会显示该代码),但永远不会被调用。这意味着该频道不会消耗任何东西。
更改为100通道只是一种临时解决方法。如果你向频道发送超过100个元素,它仍然会阻止,因为没有任何东西正在读取它。
答案 1 :(得分:1)
缓冲区大小是指您可以发送给它的多个元素而不会阻止它。默认情况下,它是0(无缓冲通道),所以如果你发送一些东西来阻塞阻塞直到通道将被goroutine读取。当您为频道设置100的大小时,该频道将在第100条消息被阻止。
答案 2 :(得分:0)
无缓冲通道的容量(可存储在通道中的元素数)为零。因此,当一个goroutine开始写入它时,它立即被阻止。当另一个goroutine从中读取该消息时解锁。
当你进行缓冲时 - 这意味着你的所有消息(至少在这种情况下100就足够了)被放入缓冲区。而且无需等到另一个goroutine将从频道
中读取它们为什么你可以在这种情况下传递几条消息?这意味着其他过程正在阅读它们。