go中管道阻塞实战

一 代码

package main

import (
   "fmt"
   "time"
)

// write Data
func writeData(intChan chan int) {
   for i := 1; i <= 50; i++ {
      // 放入数据
      intChan <- i
      fmt.Println("writeData ", i)
      // time.Sleep(time.Second)
   }
   close(intChan) // 关闭
}

// read data
func readData(intChan chan int, exitChan chan bool) {
   for {
      v, ok := <-intChan
      if !ok {
         break
      }
      time.Sleep(time.Second)
      fmt.Printf("readData 读到数据=%v\n", v)
   }
   // readData 读取完数据后,即任务完成
   exitChan <- true
   close(exitChan)
}

func main() {
   // 创建两个管道
   intChan := make(chan int, 10)
   exitChan := make(chan bool, 1)
   go writeData(intChan)
   // go readData(intChan, exitChan)
   // time.Sleep(time.Second * 10)
   for {
      _, ok := <-exitChan
      if !ok {
         break
      }
   }
}

二 测试

writeData  1
writeData  2
writeData  3
writeData  4
writeData  5
writeData  6
writeData  7
writeData  8
writeData  9
writeData  10
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:
main.main()
    E:/gocode/src/chapter16/channelapply/main.go:42 +0xa8

goroutine 18 [chan send]:
main.writeData(0xc042086000)
    E:/gocode/src/chapter16/channelapply/main.go:12 +0x54
created by main.main
    E:/gocode/src/chapter16/channelapply/main.go:38 +0x90

三 说明

1 如果注释掉 go readData(intChan, exitChan) 后,程序会报 deadlock 错误。

2 如果只是向管道写入数据,而没有读取,就会出现阻塞而 deadlock,原因是 intChan 容量是10,而代码 writeData会写入50个数据,因此会阻塞在 intChan <- i。

3 运行时,当发现一个管道只有写,而没有读,则该管道就会阻塞。

4 写管道的协程和读管道的协程如果频率不一致,没关系,就算写的比读的快也不会出现错误,底层编译系统会检测到并让程序正常运行。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值