当前位置: 代码迷 >> 综合 >> range遍历 channel 的小坑
  详细解决方案

range遍历 channel 的小坑

热度:40   发布时间:2023-10-13 08:39:38.0
package mainimport ("fmt""sync"
)var wg = sync.WaitGroup{
    }func main() {
    c := make(chan int) //无缓冲wg.Add(1)go send(c)for i := range c {
     //send()协程写完不close的话,当send()执行结束后,主协程会阻塞,至进程崩溃fmt.Println(i)}//wg.Add(1)//go recv(c)wg.Wait()
}//只能向chan里写数据
func send(c chan<- int) {
    defer wg.Done()for i := 0; i < 10; i++ {
    c <- i}//close(c)
}//只能取channel中的数据
func recv(c <-chan int) {
    defer wg.Done()for i := range c {
    fmt.Println(i)}fmt.Println("out")
}

range遍历 channel 的小坑
send()执行结束的话没有主动close, 主协程一直在读取c 中的数据,导致阻塞崩溃

package mainimport ("fmt""sync"
)var wg = sync.WaitGroup{
    }func main() {
    c := make(chan int) //无缓冲wg.Add(1)go send(c)//for i := range c { //send()协程写完不close的话,当send()执行结束后,主协程会阻塞,至进程崩溃// fmt.Println(i)//}wg.Add(1)go recv(c)wg.Wait()
}//只能向chan里写数据
func send(c chan<- int) {
    defer wg.Done()for i := 0; i < 10; i++ {
    c <- i}//close(c)
}//只能取channel中的数据
func recv(c <-chan int) {
    defer wg.Done()for i := range c {
    fmt.Println(i)}fmt.Println("out")
}

同样会崩溃 ,recv()阻塞且没有释放条件 协程泄露,不执行wg.done(),导致主协程阻塞在wg.wait(),

  相关解决方案