SoFunction
Updated on 2025-03-04

Detailed explanation of select multiplexing in golang development

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 &lt;- 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!