Go 语言 select 语句详解(并发编程)

Go 语言(Golang)中的 select 语句。这是一个在并发编程中非常重要的特性,尤其适合处理多个通道(channel)操作。select 类似于 switch 语句,但专为通道设计,能让 goroutine 等待多个通道的发送或接收操作,并执行第一个准备好的操作。
Go 的并发模型以 goroutine 和 channel 为核心,而 select 是让它们高效协作的“调度员”。它能避免死锁、实现超时控制,还能处理多路复用。

什么是 select 语句?

在 Go 中,select 语句允许一个 goroutine 同时监听多个通道操作(如发送或接收)。它会阻塞,直到至少一个 case 准备好执行;如果多个 case 同时就绪,则随机选择一个。这使得并发代码更简洁,避免了轮询通道的低效。

基本语法

select {
   
   
case <-ch1:  // 从 ch1 接收(忽略值)
    // 处理逻辑
case ch2 <- value:  // 向 ch2 发送 value
    // 处理逻辑
case x := <-ch3:  // 从 ch3 接收并赋值给 x
    // 处理逻辑
default:  // 如果没有 case 就绪,执行默认分支
    // 非阻塞处理
}
  • 阻塞行为:无 default 时,select 会等待,直到某个 case 可执行。
  • 随机选择:多 case 就绪时,随机挑选一个(伪随机)。
  • 空 selectselect {} 会永远阻塞,常用于故意挂起 goroutine。

select 是否执行所有 case?

一个常见问题是:select 会执行所有 case 吗?答案是不会select 只会执行一个就绪的 case,然后退出 select 块。以下是具体行为:

  1. 单一执行select 检查所有 case 的通道状态(发送或接收),只执行第一个就绪的 case,执行后立即退出。
  2. 随机选择:如果多个 case 同时就绪(例如多个通道有数据或可发送),select 会伪随机选择一个 case。
  3. 阻塞行为:无 default 且无 case 就绪时,select 阻塞直到有 case 可用;有 default 时,若无 case 就绪,立即执行 default
  4. 循环处理:若需处理多个通道的数据,需将 select 放在 for 循环中,逐次执行。

基本用法示例

让我们通过示例理解 select 的行为。假设有两个通道 ch1ch2,我们用 select 等待其中一个发送消息。

示例 1:监听多个接收通道

package main

import (
    "fmt"
    "time"
)

func main() {
   
   
    ch1 := make(chan string)
    ch2 := make(chan string)

    go func() {
   
   
        time.Sleep(1 * time.Second)
        ch1 <- "消息从 ch1"
    }()

    go func() {
   
   
        time.Sleep(2 * time.Second)
        ch2 <- "消息从 ch2"
    }()

    select {
   
   
    case
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值