Go Channel 详解笔记

Go Channel

Channel是Go中的一个核心类型,可以理解为一个管道,通过它并发核心单元就可以发送或者接收数据进行通讯。
操作符:<- (右写左读)

Go CSP并发模型

CSP介绍

传统的并发模型主要分为Actor模型和CSP模型,CSP全程为communicating sequential processes,CSP模型由并发执行实体(进程,线程或协程),和消息通道组成,实体之间通过消息通道发送消息进行通信。和Actor模型不同,CSP模型关注的是消息发送的载体,即通道,而不是发送消息的执行实体。其中执行实体对应的是goroutine,消息通道对应的就是channel。

Channel

channel在go中是被单独创建并且可以在进程之间传递,他的通信模式类似于 boss-worker 模式,一个实体通过将消息发送到channel中,然后又监听这个channel的实体处理,两个实体之间是匿名的,这个就是实现实体中间的解耦,其中channel是同步的一个消息被发送到channel中,最终一定是要被另外的实体消费掉的,在实现原理上其实就是一个阻塞的消息队列。

Goroutine

Goroutine是实际并发执行的实体,它底层使用协程(coroutine)实现并发,coroutine是一种运行在用户态的用户线程,go底层选择使用coroutime的出发点是因为以下三大特点:

  1. 用户空间 避免了内核态和用户态的切换导致的成本
  2. 可以由语言和框架层进行调度
  3. 更小的栈空间允许创建大量的实例
    由2可知用户空间线程的调度不是由操作系统来完成的,go提供了调度器并对网络IO库进行封装,屏蔽了复杂的细节,对外提供统一的语法关键字支持,简化了并发程序编写的成本。

Goroutine 调度器

go使用goroutine作为最小的执行单位,但是这个执行单位还在用户空间,实际上最后被处理器执行的还是内核中的线程,用户线程和内核线程的调度方法有:

  1. 多个用户线程对应一个内核线程

  2. 一个用户线程对应一个内核线程

  3. 用户线程和内核线程多对多

go通过为goroutine提供语言层面的调度器,来实现高效率的多对对线程对应关系
调度示意

  • M:内核线程
  • P:调度协调,用于协调M与G的执行,内核线程只有拿到了P才能对goroutine继续调度执行,一般都是通过限定P的个数来控制go的并发度
  • G:待执行的goroutine,包含这个goroutine的栈空间
  • Gn:灰色背景的Gn是已经挂起的goroutine,他们被添加到了执行队列中,然后需要等待网络IO的goroutine,当P通过epoll查询到特定的fd时,会重新调度对应的正在挂起的goroutine

go为了调度的公平性,在调度器中加入了steal working算法,在一个P自己的执行队列中,处理完之后,它会先到全局的执行队列中偷G进行处理,如果没有的话,再去其他P的执行队列中偷G来进行执行。

总结

go实现了CSP并发模型作为并发基础,底层使用goroutine作为并发实体,goroutine非常轻量级可以创建几十万个实体!实体间通过channel进行匿名消息传递进行解耦,在语言层面实现了自动调度,这样屏蔽了很多内部细节,对外提供简单的语法关键字,大大简化了并发编程的思维转换和管理线程的复杂度。

Channel类型

创建Channel

var c1 chan [value type]
c1 = make([channel type] [value type], [capacity])
  • [value type] 定义的是 Channel 中所传输数据的类型
  • [channel type] 定义的是 Channel 的类型,有三种类型:
    1. chan 可读可写
    2. chan<- 仅可写
    3. <-chan 仅可读
  • [capacity] 是一个可选参数,其定义的是 channel 中的缓存区。如果不填写则默认该 channel 没有缓存区。对于没有缓存区的 channel,消息的发送和收去必须能同时完成,否则会造成阻塞并提示死锁错误!

通过 Channel 发送和接收消息

示例代码:

package main
 
import "fmt"
 
func main(
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值