Go by Example: [34] Worker Pools
Worker Pools
다음의 예제는, channel
과 goroutine
을 이용해서 Worker Pool
을 구현하는 예제 입니다.
package main
import "time"
import "fmt"
func worker(id int, jobs <-chan int, results chan<- int) { // [1]
for j := range jobs {
fmt.Println("worker", id, "processing job", j)
time.Sleep(time.Second)
results <-j * 2
}
}
func main() {
jobs := make(chan int, 100) // [2]
results := make(chan int, 100)
for w := 1; w <= 3; w++ { // [3]
go worker(w, jobs, results)
}
for j := 1; j <= 9; j++ { // [4]
jobs <-j
}
close(jobs)
for a := 1; a <= 9; a++ { // [5]
<-results
}
}
- 작업함수를 선언합니다. 동시에 여러개의 함수를 실행할 것입니다. 이 작업함수는
jobs
채널에서
작업하며,results
채널에 작업결과를 전송하게 됩니다. 두번째 작업을 위해서 일정시간 대기합니다. - 현재의 작업풀(
worker pool
)에서는 작업의 수행하고 해당 수행 결과를 수집하는 것이 목적입니다.
이렇듯, 특정작업을 수행하는 것과 결과를 수집하는 2개의 채널을 생성하고 사용합니다. - 총 3개의 작업자함수를 시작하고, 현재 수행된 작업이 없으므로, 블럭상태에 둡니다.
- 9개의 작업을 처리한후 해당 채널을 종료하고 있습니다.
- 마지막으로 수집된 결과를 결과채널에(
results
) 전송합니다.
실행하면 다음과 같습니다.
$ time go run worker-pools.go
worker 1 processing job 1
worker 2 processing job 2
worker 3 processing job 3
worker 1 processing job 4
worker 2 processing job 5
worker 3 processing job 6
worker 1 processing job 7
worker 2 processing job 8
worker 3 processing job 9
real 0m3.149s
총 9개의 작업을 수행한 후 처리를 완료하는데 총 3초 가량 소요되었습니다. 이론적으로는 9초가
소요되어야 하나, 동시병렬 실행으로 작동했기때문에 3개 작업을 3번 걸쳐서 해서 3초가 소요되었습니다.