golang channel 学习笔记

channel底层结构

在这里插入图片描述

channel的类型

  1. 有缓冲。创建的时候不指定大小,常被当做信号signal来使用
  2. 无缓冲

channel的几种操作模式

写操作模式读操作模式读写操作模式
创建make(chan<-int)make(<-chan int)make(chan int)

channel的几种状态:未初始化,正常,关闭

未初始化关闭正常
关闭panicpanic正常关闭
发送永久阻塞死锁panic阻塞或成功发送
接收永久阻塞死锁缓冲区为空则为零值,否则可以正常读取阻塞或成功接收

注意:
1. 一个channel不能多次关闭,会导致panic
2. 如果多个goroutine都监听同一个channel,那么channel上的数据会被先到的goroutine取走。
3. 如果多个goroutine都监听同一个channel,当这个channel退出时,所有的监听goroutine都能收到退出信号

向channel发送数据时大概分为两步:检查和发送

  • 如果channel的读等待队列存在接收者goroutine
    将数据直接发送给第一个等待的goroutine,唤醒下一个接收的goroutine
  • 如果channel的读等待队列不存在接收者goroutine
    1. 如果循环数组buf未满,那么把待发送数据放到数组队尾
    2. 如果buf已满,这个时候就会走阻塞发送流程,将当前goroutine加入写等待队列,并挂起等待唤醒

从channel接收数据时大概分为两步:检查和数据发送

  • 如果channel的写等待队列存在发送者goroutine
    1. 如果是无缓冲channel,直接从第一个发送者goroutine那里把数据拷贝给接收变量,唤醒发送的goroutne
    2. 如果是有缓冲channel(已满),将循环数组buf的队首元素拷贝给接收变量,将第一个发送者goroutine的数据拷贝到buf循环数组队尾,唤醒发送的goroutine
  • 如果channel的写等待队列不存在发送者goroutine
    1. 如果循环数组buf非空,将循环数组buf的队首元素拷贝给接收变量
    2. 如果循环数组buf为空,这个时候就会走阻塞接收的流程,将当前goroutine加入读等待队列,并挂起等待唤醒
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值