🔥 Select

312자
4분

Go 언어에서는 고루틴을 사용하여 동시성 프로그래밍을 구현할 수 있어요. 그런데 여러 개의 고루틴이 동시에 실행될 때, 어떤 고루틴이 먼저 실행될지 예측하기 어려운 경우가 있답니다. 이럴 때 select 문을 사용하면 여러 개의 채널 중에서 하나를 선택하여 값을 주고받을 수 있어요.

select 문은 여러 개의 case 문으로 구성되는데, 각 case 문은 하나의 채널 연산을 나타내요. select 문은 case 문 중에서 실행 가능한 case 문이 있을 때까지 블로킹되며, 실행 가능한 case 문이 여러 개인 경우에는 그 중 하나를 무작위로 선택하여 실행한답니다.

아래 코드는 select 문을 사용하여 피보나치 수열을 계산하는 예제예요.

package main
 
import "fmt"
 
func fibonacci(c, quit chan int) {
	x, y := 0, 1
	for {
		select {
		case c <- x:
			// 현재 피보나치 수를 c 채널에 보냄
			x, y = y, x+y
		case <-quit:
			// quit 채널에서 값을 받으면 "quit"을 출력하고 함수 종료
			fmt.Println("quit")
			return
		}
	}
}
 
func main() {
	c := make(chan int)
	quit := make(chan int)
	go func() {
		for i := 0; i < 10; i++ {
			// c 채널에서 값을 받아서 출력
			fmt.Println(<-c)
		}
		// 10번 반복 후 quit 채널에 0을 보냄
		quit <- 0
	}()
	fibonacci(c, quit)
}
 
go

위 코드에서 fibonacci 함수는 두 개의 채널 cquit을 매개변수로 받아요. 함수 내부에서는 select 문을 사용하여 두 가지 경우를 처리하고 있어요.

  1. c <- x: 현재 피보나치 수 xc 채널에 보내고, 다음 피보나치 수를 계산합니다.
  2. <-quit: quit 채널에서 값을 받으면 "quit"을 출력하고 함수를 종료합니다.

main 함수에서는 두 개의 채널 cquit을 생성한 후, 익명 함수를 고루틴으로 실행해요. 익명 함수에서는 10번 반복하면서 c 채널에서 값을 받아 출력하고, 마지막에 quit 채널에 0을 보내죠.

fibonacci 함수를 호출할 때는 cquit 채널을 인자로 전달해요. 함수 내부에서는 select 문을 사용하여 c 채널에 피보나치 수를 보내거나 quit 채널에서 값을 받아 함수를 종료하게 됩니다.

이렇게 select 문을 사용하면 여러 개의 채널 중에서 하나를 선택하여 값을 주고받을 수 있어요. 이를 통해 고루틴 간의 정보 교환과 동기화를 효과적으로 처리할 수 있답니다.