golang面经4:channel模块

一、面试题相关

1.什么是CSP?

        CSP(Communicating Sequential Processes 通信顺序进程)是一种基于通信的并发理论,它的核心思想是:通过通信共享内存,而不是通过共享内存来通信。
具有以下特点:
        1. 避免共享内存: 协程 (Goroutine) 不直接修改变量,而是通过 Channel 通信。

        2. 天然同步:Channel 的发送/接收自带同步机制,无需手动加锁

        3. 易于组合:Channel可以嵌套使用,构建复杂并发模式(如管道、超时控制)

2. Channel的底层实现原理是怎样的?

分析:        

        channel的底层实现是一个hchan的结构,hchan的结构定义。

type hchan struct {
    qcount   uint           // 当前队列中剩余的元素个数
    dataqsiz uint           // 环形队列的大小,即可以缓存的元素数量(make(chan T, N) 中的 N)
    buf      unsafe.Pointer // 指向环形队列的指针(有缓冲 channel 才非 nil)
    elemsize uint16         // 每个元素的大小
    closed   uint32         // channel 是否已关闭的标志
    elemtype *_type         // 元素类型,用于在运行时进行类型检查
    sendx    uint           // 发送索引(send index),指向环形队列中下一个要发送的位置
    recvx    uint           // 接收索引(receive index),指向环形队列中下一个要接收的位置
    recvq    waitq          // 等待接收的 goroutine 队列(链表结构)
    sendq    waitq          // 等待发送的 goroutine 队列(链表结构)
    lock     mutex          // 互斥锁,保护 hchan 中的所有字段
}

// waitq 是一个 sudog 的链表,sudog 代表了一个等待中的 goroutine
type waitq struct {
    first *sudog
    last  *sudog
}

回答: 

Channel的底层是一个名为 hchan 的结构体, 核心包含几个关键组件:
        环形缓冲区buf : 有缓冲channel内部维护一个固定大小的环形队列, 用 buf 指针指向缓冲区, sendx 和recvx 分别记录发送和接收的位置索引。这样设计能高效利用内存,避免数据搬移。
        两个等待队列 sendq和recvq:用来管理阻塞的goroutine。sendq 存储因channel满而阻塞的发送者,recvq 存储因channel空而阻塞的接收者。 这些队列用双向链表实现, 当条件满足时会唤醒对应的goroutine。
        互斥锁:hchan 内部有个mutex,所有的发送、接收操作都需要先获取锁,用来保证并发安全。虽然看起来可能影响性能,但Go的调度器做了优化,大多数情况下锁竞争并不激烈。

补充讲一下等待队列

1. 发送等待队列 (sendq)
        作用:存储所有因无法立即发送数据而被阻塞的 goroutine。

触发条件:

无缓冲 Channel:没有接收者在等待时
有缓冲 Channel:缓冲区已满时
队列中的元素:每个被阻塞的发送者 goroutine 被打包成一个 sudog 节点。

2. 接收等待队列 (recvq)
        作用:存储所有因无法立即接收数据而被阻塞的 goroutine。

触发条件:

无缓冲 Channel:没有发送者在等待时
有缓冲 Channel:缓冲区为空时
队列中的元素:每个被阻塞的接收者 goroutine 被打包成一个 sudog 节点。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值