요약 - Worker Pool
Coddy GO 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 107개 중 66번째.
챌린지
쉬움워커 풀(worker pool) 패턴을 사용하여 작업 처리 시스템을 구축해 봅시다! 동시적으로 계산 작업을 처리하는 워커 풀을 만들어, 채널(channels), 고루틴(goroutines), 그리고 WaitGroups가 어떻게 함께 작동하여 워크로드를 효율적으로 처리하는지 실습하게 됩니다.
코드는 두 개의 파일로 구성됩니다:
pool.go: 워커 풀 구성 요소와 로직을 정의합니다.수행할 작업을 나타내는
ID(int)와Value(int) 필드를 가진Task구조체를 생성하세요.완료된 작업을 나타내는
TaskID(int)와Computed(int) 필드를 가진Result구조체를 생성하세요.워커 ID (int), 수신 전용 작업 채널(
<-chan Task), 송신 전용 결과 채널(chan<- Result), 그리고sync.WaitGroup에 대한 포인터를 매개변수로 받는Worker함수를 구현하세요. 각 워커는 다음을 수행해야 합니다:defer wg.Done()을 사용하여 완료 신호를 보냅니다.- 작업 채널을 순회(range)하며 각 작업을 처리합니다.
- 각 작업에 대해 작업의 Value의 제곱을 계산합니다.
- TaskID와 계산된 제곱값을 포함한 Result를 전송합니다.
워커 수(int)와 작업 슬라이스를 매개변수로 받는
RunPool함수를 구현하세요. 이 함수는 다음을 수행해야 합니다:- 작업과 결과를 위한 버퍼드 채널(buffered channels)을 생성합니다 (작업의 수를 버퍼 크기로 사용하세요).
- 지정된 수의 워커를 고루틴으로 시작합니다.
- 모든 작업을 작업 채널에 보내고 채널을 닫습니다.
- 모든 워커가 종료된 후 결과 채널을 닫기 위해 WaitGroup과 함께 고루틴을 사용합니다.
- 모든 결과를 슬라이스에 수집하여 반환합니다.
main.go: 입력을 읽고 워커 풀을 조정합니다.워커의 수와 작업의 수를 차례로 읽습니다. 각 작업에 대해 ID와 값을 읽습니다. 워커와 작업 목록을 사용하여
RunPool을 호출한 다음, 각 결과를Task [TaskID]: [Computed]형식으로 출력하세요.결과는 TaskID를 기준으로 오름차순 정렬하여 출력하세요.
다음과 같은 입력이 제공됩니다:
- 1행: 워커의 수 (정수)
- 2행: 작업의 수 (정수)
- 다음 행들: 각 작업에 대해 두 줄씩 - 작업 ID (정수), 그 다음 작업의 값 (정수)
예를 들어, 다음과 같이 입력되면:
2
4
1
3
2
5
3
2
4
7출력은 다음과 같아야 합니다:
Task 1: 9
Task 2: 25
Task 3: 4
Task 4: 49워커들은 작업을 동시적으로 처리하며(3의 제곱은 9, 5의 제곱은 25 등), 결과는 수집되어 작업 ID 순서대로 표시됩니다. 2개의 워커가 4개의 작업을 처리함으로써 작업이 풀 전체에 효율적으로 분산됩니다.
직접 해보기
package main
import (
"fmt"
"sort"
)
func main() {
// 작업자 수 읽기
var numWorkers int
fmt.Scanln(&numWorkers)
// 작업 수 읽기
var numTasks int
fmt.Scanln(&numTasks)
// 작업 읽기
tasks := make([]Task, numTasks)
for i := 0; i < numTasks; i++ {
var id, value int
fmt.Scanln(&id)
fmt.Scanln(&value)
tasks[i] = Task{ID: id, Value: value}
}
// TODO: 작업자와 작업을 사용하여 RunPool 호출
// TODO: TaskID를 기준으로 오름차순으로 결과 정렬
// TODO: 각 결과를 다음 형식으로 출력: Task [TaskID]: [Computed]
}
객체 지향 프로그래밍의 모든 레슨
8에러 처리와 OOP
error 인터페이스사용자 정의 에러 타입에러 래핑 (fmt.Errorf)센티넬 에러errors.Is()와 errors.As()Panic, Defer, Recover요약 - 파일 파서