select {
case <- channel1:
// 执行的代码
case value := <- channel2:
// 执行的代码
case channel3 <- value:
// 执行的代码
// 你可以定义任意数量的 case
default:
// 所有通道都没有准备好,执行的代码
}
func SimpleDemoNoDefault() {
c1 := make(chan string)
c2 := make(chan string)
go func() {
time.Sleep(1 * time.Second)
c1 <- "channel one"
}()
go func() {
time.Sleep(1 * time.Second)
c2 <- "channel two"
}()
for i := 0; i < 3; i++ {
select {
case msg1 := <-c1:
fmt.Println("received", msg1)
case msg2 := <-c2:
fmt.Println("received", msg2)
}
}
}
func SimpleDemoWithDefault() {
c1 := make(chan string)
c2 := make(chan string)
go func() {
for {
c1 <- "from 1"
}
}()
go func() {
for {
c1 <- "from 2"
}
}()
for {
time.Sleep(1 * time.Second)
select {
case msg1 := <-c1:
fmt.Println(msg1)
case msg2 := <-c2:
fmt.Println(msg2)
default:
fmt.Println("no message received")
}
}
}
通过 select 语句,可以实现主线程和其他线程之间的互动;
详情参考:
https://www.jb51.net/article/259610.htm
GoLang
实现select
时,定义了一个数据结构表示每个case
语句(包含default
,default
实际上是一种特殊的case
);select
执行过程可以看成一个函数,函数输入case
数组,输出选中的case
,然后程序流程转到选中的case
块;scase
结构体;源码包 src/runtime/select.go
type scase struct {
c *hchan // chan
elem unsafe.Pointer // data element
}
c
:表示通道,存储 case 所关联的通道,不包含 default;这也说明了一个case 语句只能操作一个 channel;elem
:表示数据类型,用于存储 case 所关联的数据元素;select {
case x := <-ch:
fmt.Println("接收到数据:", x)
case ch <- 10:
fmt.Println("发送数据成功")
default:
fmt.Println("没有进行任何操作")
}
<-ch
:表示接收操作,将通道 ch 中的数据赋值给变量 x;ch <- 10
:表示发送操作,将数据 10 发送到通道 ch 中;default
:表示默认操作,当没有其他 case 可执行时,执行该操作;func MultiChannelRead() {
ch1 := make(chan int)
ch2 := make(chan int)
go func() {
ch1 <- 1
}()
go func() {
ch2 <- 2
}()
select {
case data := <-ch1:
fmt.Println("received data from ch1: ", data)
case data := <-ch2:
fmt.Println("receiver data from ch2: ", data)
}
}
func MultiChannelWrite() {
ch1 := make(chan int)
ch2 := make(chan int)
go func() {
ch1 <- 1
}()
go func() {
ch2 <- 2
}()
select {
case <-ch1:
fmt.Println("Send data to ch1")
case <-ch2:
fmt.Println("Send data to ch2")
}
}
func TimeoutControl() {
ch := make(chan int)
go func() {
time.Sleep(2 * time.Second)
}()
select {
case data := <-ch:
fmt.Println("Received data: ", data)
case <-time.After(1 * time.Second):
fmt.Println("Timeout occurred")
}
}