예제 패키지
예제 패키지
지금까지 배운 문법들이 실제로는 어떻게 한데 묶이는지, 작동하는 완전한 Go 패키지 하나를 보면 훨씬 빨리 감이 잡혀요. 여기 아래에 소수를 찾아내는 **동시성(concurrent) 소수 체(prime sieve)**를 구현한 완전한 Go 패키지가 있습니다.
출처: Go Specification
본문
이 패키지는 generate에서 숫자를 하나씩 보내고, 그 숫자를 filter가 소수로 나눠 걸러내는 방식으로 소수를 차례로 뽑아내요. 채널(chan)을 통해서 값이 흐르고, go 키워드로 각 함수를 별도의 프로세스(고루틴)로 띄워 데이지체인처럼 이어 붙이는 구조죠.
package main
import "fmt"
// Send the sequence 2, 3, 4, … to channel 'ch'.
func generate(ch chan<- int) {
for i := 2; ; i++ {
ch <- i // Send 'i' to channel 'ch'.
}
}
// Copy the values from channel 'src' to channel 'dst',
// removing those divisible by 'prime'.
func filter(src <-chan int, dst chan<- int, prime int) {
for i := range src { // Loop over values received from 'src'.
if i%prime != 0 {
dst <- i // Send 'i' to channel 'dst'.
}
}
}
// The prime sieve: Daisy-chain filter processes together.
func sieve() {
ch := make(chan int) // Create a new channel.
go generate(ch) // Start generate() as a subprocess.
for {
prime := <-ch
fmt.Print(prime, "\n")
ch1 := make(chan int)
go filter(ch, ch1, prime)
ch = ch1
}
}
func main() {
sieve()
}
흐름을 한 번 따라가 볼게요. sieve()가 채널 하나를 만들고 generate를 고루틴으로 시작해요. 그러면 generate가 2부터 무한히 숫자를 보내죠. sieve()의 for 루프에서 채널에서 첫 값을 꺼내면 그게 소수이고, 바로 출력한 뒤 그 소수로 걸러내는 filter를 새로 띄워 채널을 이어 붙여요. 이걸 반복하면서 2, 3, 5, 7… 소수만 남게 되는 원리예요.
더 알아보기
- 여기서 쓰인 채널(
chan) 문법은 채널 타입 섹션에서 더 자세히 다뤄요. go키워드로 시작하는 고루틴과 프로그램이 실제로 어떻게 실행되는지는 프로그램 초기화와 실행 섹션에서 볼 수 있어요.