golang基础--chan

了解chan

在 Go(Golang)中,chan 是用来实现 goroutine 之间通信的管道(Channel)。它允许你在线程之间安全地传递数据。

创建chan

go 复制代码
chOne := make(chan int) // 创建一个整型的无缓冲 Channel
chTwo := make(chan string, 2) // 创建一个字符串的缓冲 Channel,容量为 2

发送和接收数据

无缓冲的 Channel 在发送或接收时会阻塞,直到另一端准备好。

go 复制代码
ch := make(chan int)

// 发送数据到 Channel
go func() {
    fmt.Println("1秒后向chan发送数据")
    time.Sleep(1 * time.Second)
    ch <- 1
}()

// 从 Channel 接收数据
fmt.Println("main等待接收数据")
data := <-ch
fmt.Println(data) // 输出: 1
fmt.Println("结束进程")

运行结果 带缓冲的chan

  • 缓冲 Channel 可以存储有限数量的数据,而不需要立即被消费。
  • 如果缓冲已满,发送操作会阻塞,直到缓冲中有空位。
go 复制代码
ch := make(chan int, 2)

ch <- 1
fmt.Println("这里不会阻塞")
ch <- 2

fmt.Println(<-ch) // 输出: 1
fmt.Println(<-ch) // 输出: 2

运行结果

使用 select 语句

select 用于同时监听多个 Channel 的读写操作。

go 复制代码
ch1 := make(chan int)
ch2 := make(chan string)

go func() {
    ch1 <- 1
}()
go func() {
    ch2 <- "Hello"
}()

select {
case msg := <-ch1:
    fmt.Println("接收到数据 ch1:", msg)
case msg := <-ch2:
    fmt.Println("接收到数据 ch2:", msg)
default:
    fmt.Println("无数据")
}
  • select可以同时监听多个ch,上面代码中,那个先接收到数据就执行那个case
  • 如果有default,ch1,ch2为空的情况下,执行default 不堵塞
  • 如果没有default,ch1,ch2为空的情况下,select 会堵塞,直到ch1或ch2任何一个有值
  • 直接使用select{} 不设置任何case,也会导致当前方法堵塞

运行结果

ps : 这个结果是随机的,取决那个case先接收到数据,如果两个go协程没有先于select执行,也就是ch1,ch2还没有值,就执行default 无数据

关闭 Channel

使用 close() 关闭 Channel,表示没有更多数据会发送到这个 Channel。

  • 关闭 Channel 后再发送数据会导致 panic。
  • 从已关闭的 Channel 接收数据会返回零值。
  • 可以通过接收第二个值来检测 Channel 是否已关闭。
go 复制代码
ch := make(chan int)

go func() {
    for i := 0; i < 3; i++ {
       time.Sleep(1 * time.Second)
       ch <- i
    }
    close(ch) // 关闭 Channel
}()

for val := range ch { // 使用 range 读取 Channel,直到关闭
    fmt.Println(val)
}

// chan的第二个值可以判断chan是否被关闭,类似map取值
chHas := make(chan int)
close(chHas)

val, ok := <-chHas
fmt.Println(val, ok) // 输出: 0 false
fmt.Println("程序结束")

运行结果

使用场景

  • 数据流传递:goroutine 之间传递数据。
  • 任务协调:通过 Channel 来同步任务。
  • 信号通知:通过关闭 Channel 实现广播信号。

通过 chanselect,可以轻松实现高并发任务的同步和数据通信,是 Go 并发编程的核心之一。

相关推荐
想用offer打牌18 分钟前
高并发下如何保证接口的幂等性
后端·面试·状态机
爱勇宝1 小时前
2026一人公司生存指南:用AI大模型,90天跑出你的第一条现金流
前端·后端·架构
golang学习记1 小时前
Go 并发编程:原子操作(Atomics)完全指南
后端
哈里谢顿2 小时前
`127.0.0.1` 和 `0.0.0.0` 有何区别?通过验证 demo来展示
后端
树獭叔叔2 小时前
08-大模型后训练的指令微调SFT:LoRA让大模型微调成本降低99%
后端·aigc·openai
苏三说技术2 小时前
我终于遇到一台真正懂程序员的显示器!
后端
Re_zero2 小时前
线上日志被清空?这段仅10行的 IO 代码里竟然藏着3个毒瘤
java·后端
花落人散处2 小时前
流式输出——解决 HITL 难题 (SpringAIAlibaba)
后端
BingoGo4 小时前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack4 小时前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端