package main
import (
"fmt"
"sync"
)
func main() {
wg := sync.WaitGroup{}
var ret = make(chan int)
for i := 0; i < 100; i++ {
wg.Add(1)
go func(i int) {
ret <- i
wg.Done()
}(i)
}
go func() {
defer close(ret)
wg.Wait()
}()
fmt.Println("执行结束")
for v := range ret {
fmt.Println(v)
}
}
上段代码中
go func() {
defer close(ret)
wg.Wait()
}()
为什么不能替换成:
wg.Wait()
close(ret)
有疑问加站长微信联系(非本文作者)

我自己想应该是使用
阻碍的主线程,但是同时遍历是发生在主线程上。这时候定义的channel是无缓存的,这时候没办法发现这个无缓冲的channel又被消费的可能,故而会发生异常。这时候使用 协程的话,由于不堵塞。使得 channel消费成为的可能。
关注
啥也不是,就是基础没学好
我大概知道 为什么了
wg.wait是阻塞的 是需要等待上面 100个阻塞的 goroutine 执行完成之后 才能继续往下执行
但是这100个 goroutine 可以完成的前提是 ret 这个chanel的数据 呗读取 就是需要下面的 range 来执行 才可以 让这goroutine 完成
但是 wg.wait 阻塞了 就没法继续往下执行下去
不是,是当执行完100个goroutine后,ret没有被关闭,所以在下面的range ret中持续阻塞式接收数据,就没法继续往下执行下去。 所以需要再开一个goroutine,去等待所有goroutine结束后关闭channel。
你这样搞的话,Wait得等到ret写100个后退出同步,ret得等到range准备好后才能写入,range得等到Wait退出同步才能执行,死锁