select is a control structure in Golang, syntactically similar to a switch statement, except that select is used for communication between goroutines. Each case must be a communication operation, either sending or receiving, and select will randomly execute a runnable case. If there is no case to run, goroutine will block until a case to run.
select multiple selection
The way of writing select is basically the same as the way of writing switch case, except that golang's select is a communication control statement. The execution of select must be sent or accepted by communication, and if not, it will be blocked.
ch := make(chan bool, 0) ch1 := make(chan bool, 0) select { case ret := <-ch: (ret) case ret := <-ch1: (ret) }
If neither ch nor ch1 communicates with data, select will block until ch or ch1 has data sent, select will execute the corresponding case to receive data.
select implements timeout control
We can use the select mechanism to implement a simple timeout control.
Let's look at the complete code of the program
func service(ch chan bool) { (*3) ch<-true } func main() { ch := make(chan bool, 0) go service(ch) select { case ret := <-ch: (ret) case <-(*5): ("timeout") } } ___go_build_main_go #gosetup true
You can see that 5S is defined using timeout, and the service program executes 3S, so there is definitely no timeout, which is consistent with the expected one.
Let's look at the execution of timeout again. We will set the execution time of the service program to be 6S. The timeout control continues to be 5S, and then check the execution effect
func service(ch chan bool) { (*6) ch<-true } func main() { ch := make(chan bool, 0) go service(ch) select { case ret := <-ch: (ret) case <-(*5): ("timeout") } } ___go_build_main_go #gosetup timeout
The execution of the timeout case is actually consistent with what you expected.
select determines whether the channel is closed
Let's look at the syntax for accepting data first
val,ok <- ch ok true Receive data normally ok false Channel close
You can see that there are actually two parameters to accept data. The second bool value will reflect whether the channel is closed and whether the data can be accepted normally.
Check out the test code
We wrote a data sender and two data recipients. When the sender closes the channel, the goroutines of the two recipients can determine whether the channel is closed through the above syntax and decide whether the goroutine is over.
func sender(ch chan int, wg *) { for i:=0;i<10;i++ { ch<-i } close(ch) () } func receiver(ch chan int, wg *) { for { if val,ok := <-ch;ok { (("%d,%s",val, "revevier")) } else { ("quit recevier") break; } } () } func receiver2(ch chan int, wg *) { for { if val,ok := <-ch;ok { (("%d,%s",val, "revevier2")) } else { ("quit recevier2") break; } } () } func main() { ch := make(chan int, 0) wg := &{} (1) go sender(ch, wg) (1) go receiver(ch, wg) (1) go receiver2(ch, wg) () }
Execution results
0,revevier2
2,revevier2
3,revevier2
4,revevier2
5,revevier2
6,revevier2
7,revevier2
1,revevier
9,revevier
quit recevier
8,revevier2
quit recevier2
You can see a data sender and two data recipients. When the channel is closed, both data recipients receive a notification that the channel is closed.
It should be noted that if you send data to a closed channel, the program will panic and receive data from a closed channel. It will receive 0-value data of channel type without reference meaning. Int is 0, and string is empty...
select Exit timer and other programs
The training timer is often used in development, but the training timer cannot be turned off when the program exits. In fact, select can solve this problem.
If we have a rotation training task, we need a timer, and we execute logic every 3S, and close this timer after 10S.
Look at the code
func TimeTick(wg *,q chan bool) { defer () t := (*3) defer () for { select { case <-q: ("quit") return case <-: ("seconds timer") } } } func main() { q := make(chan bool) wg := new() (1) go TimeTick(wg,q) (*10) close(q) () }
Execution results
seconds timer
seconds timer
seconds timer
quit
Very elegantly exit the training timer by closing the channel goroutine,
This is the end of this article about select multiplexing in golang development. For more related golang select multiplexing content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!