首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >channel 基本概念

channel 基本概念

原创
作者头像
浩瀚星河
发布2025-08-05 11:33:21
发布2025-08-05 11:33:21
2280
举报
文章被收录于专栏:golanggolang

chan 是 golang 中的数据结构,俗称管道,用于并发控制和阻塞,其实不也不太懂一步步来

创建

channel 只能使用 make 来创建

代码语言:go
复制
c := make(chan int) // 创建无缓冲区的chan

c2 := make(chan int,2) // 创建2个缓冲区的chan

这个无缓冲区的 channel 一旦接收了值就会在当前 goroutines 阻塞

所以一般配合 goroutines 在后台使用

无缓冲区的 channel

无缓冲区的 channel 在一个地方接收值只能等待接收方接收才能进行下一次读入

代码语言:go
复制
package main

import (
	"fmt"
	"time"
)

func main() {
	c := make(chan int)
	go func() {
		fmt.Println("[Goroutine] Send 1")
		c <- 1
		fmt.Println("[Goroutine] Send 2")
		c <- 2
	}()

	time.Sleep(time.Millisecond * 10) // 稍等,确保 goroutine 启动

	fmt.Println("[Main] Receive 1")
	v1 := <-c
	fmt.Println("[Main] Got:", v1)

	fmt.Println("[Main] Receive 2")
	v2 := <-c
	fmt.Println("[Main] Got:", v2)
}

执行结果:

代码语言:go
复制
[Goroutine] Send 1
[Main] Receive 1
[Main] Got: 1
[Main] Receive 2
[Goroutine] Send 2
[Main] Got: 2

正如上述代码所示,往 无缓冲的 channel 置入值,接收值这个过程会阻塞当前goroutine,直到在另外一个 goroutine 拿到为止

代码语言:go
复制
v3 := <-c
fmt.Println("[Main] Got:", v3)

如果写成这样那么就会持续阻塞,造成死锁问题

控制台的输出为

代码语言:bash
复制
fatal error: all goroutines are asleep - deadlock!
]:
main.main()
        /code/demo/eventbus/1.go:27 +0x214

有缓冲区的 channel

与无缓冲区的 channel 不同的是,有缓冲区的 channel 内部是可以存储值的,如果在没有接收方时,依旧是可以往 channel 发送值,直到发送的值的个数等于缓冲区容量的时候,channel 就会被阻塞

代码语言:go
复制
package main

import (
	"fmt"
	"time"
)

func main() {
	c := make(chan int, 2)
	go func() {
		fmt.Println("[Goroutine] Send 1")
		c <- 1
		fmt.Println("[Goroutine] Send 2")
		c <- 2
	}()

	time.Sleep(time.Millisecond * 10) // 稍等,确保 goroutine 启动

	fmt.Println("[Main] Receive 1")
	v1 := <-c
	fmt.Println("[Main] Got:", v1)

	fmt.Println("[Main] Receive 2")
	v2 := <-c
	fmt.Println("[Main] Got:", v2)
}

执行结果:

代码语言:bash
复制
[Goroutine] Send 1
[Goroutine] Send 2
[Main] Receive 1
[Main] Got: 1
[Main] Receive 2
[Main] Got: 2

可以发现,有缓冲区并不像无缓冲区那样,在置入一个值就会阻塞,当前goroutine 会被挂起,有缓冲区的 channel 可以往内部置入多个值,仅当发送个数等于其缓冲区容量的时候,才会被挂起

所以无缓冲区是同步的,在消费者消费完才能继续生产

有缓冲区是异步的,无需等待消费者消费完

无缓冲区有点像一个共用的杯子,只有牛奶满了,顾客才能购买并且喝完才能继续挤奶

有缓冲区就是一个车间,可以一直生产牛奶直到车间满为止,消费者是可以直接去车间喝牛奶的

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 创建
  • 无缓冲区的 channel
  • 有缓冲区的 channel
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档