我正在使用缓冲通道,我得到了我需要的正确输出。package mainimport ( "fmt" "sync")var wg sync.WaitGrouptype Expert struct { name string age int}func main() { fmt.Println("==== GoRoutines ====") expertChannel := make(chan Expert, 3) wg.Add(1) go printHello() wg.Add(1) go addDataToChannel(expertChannel, "Name", 24) wg.Add(1) go addDataToChannel(expertChannel, "Name", 24) wg.Add(1) go addDataToChannel(expertChannel, "Name", 24) wg.Wait() close(expertChannel) for x := range expertChannel { fmt.Println("Expert Data :: ", x) }}func printHello() { for i := 1; i <= 5; i++ { fmt.Println("This is from PrintHello() Function where i = ", i) } defer wg.Done()}func addDataToChannel(c chan Expert, name string, age int) { defer wg.Done() c <- Expert{ name, age, }}但是当我使用unBuffered通道时,我得到了错误,这是致命的错误:所有goroutines都睡着了 - 死锁!为什么会发生这种情况以及如何解决这个问题?package mainimport ( "fmt" "sync")var wg sync.WaitGrouptype Expert struct { name string age int}func main() { fmt.Println("==== GoRoutines ====") expertChannel := make(chan Expert) wg.Add(1) go printHello() wg.Add(1) go addDataToChannel(expertChannel, "Name", 24) wg.Add(1) go addDataToChannel(expertChannel, "Name", 24) wg.Add(1) go addDataToChannel(expertChannel, "Name", 24) wg.Wait() close(expertChannel) for x := range expertChannel { fmt.Println("Expert Data :: ", x) }}func printHello() { for i := 1; i <= 5; i++ { fmt.Println("This is from PrintHello() Function where i = ", i) } defer wg.Done()}func addDataToChannel(c chan Expert, name string, age int) { defer wg.Done() c <- Expert{ name, age, }}我们什么时候会使用缓冲通道,什么时候会使用无缓冲通道 如何识别两个通道类别的用例?
1 回答

皈依舞
TA贡献1851条经验 获得超3个赞
如果缓冲区已满,则通过通道发送和接收将阻塞。对于无缓冲通道,因为它没有缓冲区,除非在另一端读取数据,否则它会立即阻塞。
将第一个数据发送到通道后,除非读取,否则没有其他例程的空间将数据发送到通道。因此,发件人被阻止。
您需要取消阻止从通道读取的主要例程。以便发送方找到空间继续向通道发送数据。
现在wg.Wait() 阻塞并且不允许主例程(for 循环)从通道读取。一旦它开始从通道读取,被阻止的发送者也可以恢复并可以发送更多数据。
做wg。wait() 在并发 go 例程中:
go func() {
wg.Wait()
close(expertChannel)
}()
- 1 回答
- 0 关注
- 105 浏览
添加回答
举报
0/150
提交
取消