[Go] Detailed explanation of select statement

Table of contents

select statement


selectsentence

selectStatements are used extensively in the Go language as a control structure for selecting among multiple communication operations. Here are selecta few common uses of statements:

  1. Multi-channel selection: selectThe statement can monitor the read and write operations of multiple channels at the same time, and select one of the executable operations for processing. Through selectstatements, multiplexing in concurrent programs can be realized to avoid blocking and waiting. This is selectone of the most common uses of statements.
select {
case <-channel1:
    // 处理channel1接收操作
case data := <-channel2:
    // 处理channel2接收操作
case channel3 <- value:
    // 处理channel3发送操作
default:
    // 当没有任何通信可用时执行该分支
}
  • Timeout processing: selectStatements can time.Afterbe used in conjunction with functions to implement timeout control over operations. By selectadding a timer channel in the statement, you can wait for the completion of the operation within the specified time, and perform timeout processing if the set time is exceeded.
timeout := time.After(5 * time.Second)
select {
case result := <-dataChannel:
    // 处理接收到的数据
case <-timeout:
    // 执行超时处理
}
  • Blocking and non-blocking options: selectStatements can cooperate with defaultbranches to implement non-blocking communication operations. When no communication is available, selectthe statement immediately executes defaultthe code in the branch without blocking waiting.
select {
case data := <-channel:
    // 处理接收到的数据
default:
    // 没有任何通信可用时立即执行该分支
}
  • Program exit control: selectstatements can be used in conjunction with special exit channels to control program exit. By listening to the exit channel, the exit operation can be triggered when the program needs to end.
done := make(chan bool)
select {
case <-interruptChannel:
    // 处理中断事件
    done <- true
case <-terminateChannel:
    // 处理终止事件
    done <- true
case <-done:
    // 接收到退出信号,结束程序
}
  • select can monitor one or more channels at the same time until one of the channels is ready
package main

import (
	"fmt"
	"time"
)

func test1(ch chan string) {
	time.Sleep(time.Second * 5)
	ch <- "test1"
}
func test2(ch chan string) {
	time.Sleep(time.Second * 2)
	ch <- "test2"
}

func main() {
	// 2个管道
	output1 := make(chan string)
	output2 := make(chan string)
	// 跑2个子协程,写数据
	go test1(output1)
	go test2(output2)
	// 用select监控
	select {
	case s1 := <-output1:
		fmt.Println("s1=", s1)
	case s2 := <-output2:
		fmt.Println("s2=", s2)
	}
}

  • If multiple channels are ready at the same time, randomly select one to execute

 

package main

import (
   "fmt"
)

func main() {
   // 创建2个管道
   int_chan := make(chan int, 1)
   string_chan := make(chan string, 1)
   go func() {
      //time.Sleep(2 * time.Second)
      int_chan <- 1
   }()
   go func() {
      string_chan <- "hello"
   }()
   select {
   case value := <-int_chan:
      fmt.Println("int:", value)
   case value := <-string_chan:
      fmt.Println("string:", value)
   }
   fmt.Println("main结束")
}

Guess you like

Origin blog.csdn.net/fanjufei123456/article/details/131315632