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 并发编程的核心之一。

相关推荐
千叶寻-1 小时前
正则表达式
前端·javascript·后端·架构·正则表达式·node.js
小咕聊编程2 小时前
【含文档+源码】基于SpringBoot的过滤协同算法之网上服装商城设计与实现
java·spring boot·后端
追逐时光者8 小时前
推荐 12 款开源美观、简单易用的 WPF UI 控件库,让 WPF 应用界面焕然一新!
后端·.net
Jagger_8 小时前
敏捷开发流程-精简版
前端·后端
苏打水com9 小时前
数据库进阶实战:从性能优化到分布式架构的核心突破
数据库·后端
间彧10 小时前
Spring Cloud Gateway与Kong或Nginx等API网关相比有哪些优劣势?
后端
间彧10 小时前
如何基于Spring Cloud Gateway实现灰度发布的具体配置示例?
后端
间彧10 小时前
在实际项目中如何设计一个高可用的Spring Cloud Gateway集群?
后端
间彧10 小时前
如何为Spring Cloud Gateway配置具体的负载均衡策略?
后端
间彧10 小时前
Spring Cloud Gateway详解与应用实战
后端