You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言中向超容量的缓冲channel写入数据是否会产生影响?

问题解答:Go语言超容量缓冲channel写入的影响

首先明确结论:向已满的缓冲channel写入数据时,执行写入操作的goroutine会直接阻塞,不会抛出异常、也不会丢失待写入的数据,直到有其他goroutine从该channel读取了数据、腾出空闲缓冲位置,阻塞的goroutine才会被唤醒继续执行写入。

你描述的「子goroutine独立执行写入、主goroutine无需等待子goroutine完成」的场景,确实不会触发死锁:Go的死锁检测只会在所有goroutine都处于阻塞状态时才会触发,该场景下主goroutine可以正常执行读取/其他逻辑,不会出现全局阻塞的情况。

示例代码执行逻辑说明

你提供的代码运行逻辑如下:

  • 初始化容量为2的int类型缓冲channel,最多可以暂存2个元素
  • 子goroutine启动后依次写入1、2,此时channel被填满,写入4的操作会立刻阻塞,Go调度器会切换执行主goroutine
  • 主goroutine依次读取channel中的1、2并打印,此时channel缓冲被清空,阻塞的子goroutine被唤醒继续写入4、6,写入10时因为channel再次被填满会再次阻塞
  • 现有代码中主goroutine读完2个元素后就会直接退出,整个程序终止,因此后续的4、6、10不会被输出;如果放开注释中的close(ch)和range遍历逻辑,就可以顺序读取到所有写入的5个值。
package main

import "fmt"

func main() {
    ch := make(chan int, 2)
    go func (){
    ch <- 1
    ch <- 2
    ch <- 4//在此处阻塞,但调度器会调度其他goroutine执行
    ch <- 6
    ch <- 10
    //close(ch)
    }()
    fmt.Println(<-ch)
    fmt.Println(<-ch)
    //for v:=range ch{
    //fmt.Println(v)//1 2 4 6 10
    //}
}

额外注意:如果该channel后续始终没有任何goroutine执行读取操作,阻塞的写入goroutine会一直驻留内存无法释放,会造成goroutine泄漏,属于开发中需要避免的问题。

内容的提问来源于stack exchange,提问作者mohammed yaqub

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 22:24:00