[Golang] Select

[Golang] Select

文章目录

什么是select

select是Golang中一个控制结构,可以用来处理多个channel的发送和接收操作。select会阻塞,直到其中一个case可以执行,然后执行该case。如果有多个case可以执行,则随机执行一个case。

select用法

基本用法

go 复制代码
package main

func main() {
	ch1 := make(chan int,1)
	ch2 := make(chan int)
	select {
		case <-ch1:
		// ...  如果ch1读取成功,则执行该case
		case ch2<-1:
		//...  如果ch2写入成功,则执行该case
		default:
		//...  如果都不成功,执行default
	}
}

select的用法和switch比较相似,不过select的每个case表达式都是channel的读写操作,通过多个case语句

监听多个channel的读写操作是否可以执行;如果没有可以执行的case,就执行default;如果没有default,则当前goroutine会被阻塞。

空select

如果select中什么语句都没有,就会被永久阻塞。

go 复制代码
package main

func main() {
	select {
	}
}

执行结果:

golang自带的死锁检测,发现当前goroutine永久不会被唤醒,就会报死锁错误。

没有default且case永久无法执行

go 复制代码
package main

import "fmt"

func main() {
	ch1 := make(chan int, 1)
	ch2 := make(chan int, 1)
	select {
	case <-ch1:
		fmt.Println("123")
	case <-ch2:
		fmt.Println("456")
	}
}

执行结果:

两个channel中都没有数据,所以读不出数据,该goroutine会被永久阻塞,

单个case和default

go 复制代码
package main

import (
	"fmt"
	"sync"
)

func main() {
	var wg sync.WaitGroup
	wg.Add(1)
	ch1 := make(chan int, 1)
	go func() {
		defer wg.Done()
		for i := 0; i < 5; i++ {
			select {
			case <-ch1:
				fmt.Println("123")
			default:
				fmt.Println("default")
			}
		}
	}()
	wg.Wait()
}

执行结果:

多个case和default

go 复制代码
package main

import (
	"fmt"
)

func main() {
	ch1 := make(chan int, 1)
	ch2 := make(chan int, 1)

	ch1 <- 1
	ch2 <- 2

	select {
	case <-ch1:
		fmt.Println("123")
	case <-ch2:
		fmt.Println("ABC")
	default:
		fmt.Println("default")
	}

}

执行结果:

有多个case准备好时,会随机执行一个case。

IO多路复用

看到select大家都会联想到Linux中的IO多路复用模型select、poll、epoll,IO多路复用模型是为了提升程序的处理IO时间的性能,其实golang中的select和它们还是有一定区别的。

操作系统的IO多路复用,其实就可以理解为一个或少量线程处理多个IO事件。

传统的阻塞IO:可以理解为一个线程去处理一个IO事件,如果IO事件还没就绪,就阻塞等待。

IO多路复用:一个或少量线程处理多个IO事件。

golang中的select,就是用一个goroutine去监听多个channel的读写事件,提高从多个channel获取信息的效率,也可以理解为一个线程去监控多个IO事件。

相关推荐
执风挽^42 分钟前
Python基础编程题2
开发语言·python·算法·visual studio code
程序员泠零澪回家种桔子44 分钟前
Spring AI框架全方位详解
java·人工智能·后端·spring·ai·架构
Z9fish1 小时前
sse哈工大C语言编程练习20
c语言·开发语言·算法
萧鼎1 小时前
Python 包管理的“超音速”革命:全面上手 uv 工具链
开发语言·python·uv
源代码•宸2 小时前
大厂技术岗面试之谈薪资
经验分享·后端·面试·职场和发展·golang·大厂·职级水平的薪资
Anastasiozzzz2 小时前
Java Lambda 揭秘:从匿名内部类到底层原理的深度解析
java·开发语言
刘琦沛在进步2 小时前
【C / C++】引用和函数重载的介绍
c语言·开发语言·c++
机器视觉的发动机2 小时前
AI算力中心的能耗挑战与未来破局之路
开发语言·人工智能·自动化·视觉检测·机器视觉
HyperAI超神经2 小时前
在线教程|DeepSeek-OCR 2公式/表格解析同步改善,以低视觉token成本实现近4%的性能跃迁
开发语言·人工智能·深度学习·神经网络·机器学习·ocr·创业创新
晚霞的不甘2 小时前
CANN 编译器深度解析:UB、L1 与 Global Memory 的协同调度机制
java·后端·spring·架构·音视频