Golang 9 - Concurrency - Select


Written on March 16, 2024

Select là gì

select dùng để chọn từ nhiều channel gửi/nhận. Select được block cho tới khi môt channel sẵn sàng. Nếu nhiều channel cùng sẵn sàng, một channel sẽ được chọn ngẫu nhiên. Syntax tương tự như switch ngoại trừ mỗi case sẽ là channel.

Ví dụ

package main

import (
	"fmt"
	"time"
)

func server1(ch chan string) {
	time.Sleep(6 * time.Second)
	ch <- "from server1"
}
func server2(ch chan string) {
	time.Sleep(3 * time.Second)
	ch <- "from server2"

}
func main() {
	output1 := make(chan string)
	output2 := make(chan string)
	go server1(output1)
	go server2(output2)
	select {
	case s1 := <-output1:
		fmt.Println(s1)
	case s2 := <-output2:
		fmt.Println(s2)
	}
}

Main function call 2 Goroutine lần lượt server1server2. The select ở main func sẽ bị blocks cho tới khi một case sẵn sàng. Output của chương trình:

from server2

Ứng dụng của select

Giả sử chúng ta có một critial application và cần trả về output cho users as quickly as possible. Database được replicated and stored ở những server khác nhau trên thế giới. Thời gian phản hồi của mỗi servers phụ thuộc vào nhiều yếu tố ví dụ như network deplay. Chúng ta send request tới cả 2 servers và đợi trên các channel tương ứng bằng cách sử dụng select statement. Server nào responds trước sẽ được chọn và cái kia sẽ bị ignore.

Default case

Default case trong select statement được thực thi khi không có cases nào sẵn sàng. Mục tiêu là để tránh trường hợp select statmentn bị blocking.

Deadlock and default case

Random selection

Empty select