| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
| 29 | 30 | 31 |
Tags
- goroutines
- channel
- method
- cli
- TODO
- Vue.js
- Server
- Dictionary
- SFC
- graceful shutdown
- URL
- 행렬
- CDN
- toggle
- Refactoring
- App.vue
- todo-list
- golang
- go
- Matrix
- emit
- container
- goroutine
- map
- reactivity
- Vue
- websocket
- PROPS
- localStorage
- component
Archives
- Today
- Total
ksundev 님의 블로그
Channels 2 - chan 타입 바꾸고 반복문 활용하기 본문
Channels 2 - chan 타입 바꾸고 반복문 활용하기
1. 코드 분석
현재 우리가 살펴볼 코드는 문자열 타입 채널과 반복문을 활용한 개선된 예제입니다:
package main
import (
"fmt"
"time"
)
func main() {
c := make(chan string)
people := [4]string{"KSun", "Peter", "John", "Chris"}
for _, person := range people {
go isReady(person, c)
}
for i := 0; i < len(people); i++ {
fmt.Println("Received:", <-c)
}
}
func isReady(person string, c chan string) {
time.Sleep(time.Second * 5)
c <- person + " is ready"
}
2. 이전 코드와의 차이점
2.1 채널 타입 변경
// 이전: bool 타입 채널
c := make(chan bool)
// 현재: string 타입 채널
c := make(chan string)
2.2 더 풍부한 정보 전달
// 이전: 단순한 완료 신호
c <- true
// 현재: 구체적인 메시지 전달
c <- person + " is ready"
2.3 동적 메시지 수신
// 이전: 하드코딩된 2번의 수신
fmt.Println("Received:", <-c)
fmt.Println("Received:", <-c)
// 현재: 배열 길이에 따른 동적 수신
for i := 0; i < len(people); i++ {
fmt.Println("Received:", <-c)
}
3. 코드 동작 과정
3.1 채널 생성
c := make(chan string)
string타입의 언버퍼드 채널을 생성합니다- 이제 문자열 메시지를 주고받을 수 있습니다
3.2 고루틴 시작
people := [4]string{"KSun", "Peter", "John", "Chris"}
for _, person := range people {
go isReady(person, c)
}
- 4개의 고루틴이 동시에 시작됩니다
- 각 고루틴은 서로 다른 사람의 이름을 받습니다
3.3 고루틴 함수 분석
func isReady(person string, c chan string) {
time.Sleep(time.Second * 5) // 5초 대기
c <- person + " is ready" // 개인화된 메시지 전송
}
- 각 고루틴은 5초 동안 대기한 후
- 해당 사람의 이름을 포함한 개인화된 메시지를 채널에 전송합니다
3.4 메인 고루틴에서 메시지 수신
for i := 0; i < len(people); i++ {
fmt.Println("Received:", <-c)
}
len(people)만큼 반복하여 모든 고루틴의 완료를 기다립니다- 배열 크기가 변경되어도 자동으로 모든 메시지를 수신합니다
4. 실행 결과
이 코드를 실행하면 다음과 같은 결과가 나옵니다:
Received: KSun is ready
Received: John is ready
Received: Chris is ready
Received: Peter is ready순서는 매번 다를 수 있습니다! 고루틴이 동시에 실행되므로 완료 순서는 실행할 때마다 달라집니다.
5. 핵심 개선사항
5.1 유연한 인원 조정
// 3명으로 변경
people := [3]string{"KSun", "Peter", "John"}
// 5명으로 변경
people := [5]string{"KSun", "Peter", "John", "Chris", "Alice"}
// 10명으로 변경
people := [10]string{"KSun", "Peter", "John", "Chris", "Alice", "Bob", "Eve", "Frank", "Grace", "Henry"}
코드를 수정하지 않고도 배열만 변경하면 원하는 만큼의 사람을 처리할 수 있습니다!
5.2 자동 동기화
- 배열 크기가 변경되어도 자동으로 모든 고루틴의 완료를 기다립니다
- 누락된 메시지나 추가 수신 없이 정확히 처리됩니다
6. 성능 특성
6.1 병렬 처리
- 4명의 사람이 각각 5초씩 작업하지만
- 총 실행 시간은 여전히 5초입니다 (병렬 실행)
6.2 메모리 효율성
- 하나의 채널로 모든 고루틴과 통신
- 각 고루틴은 독립적으로 실행되며 메모리를 효율적으로 사용
7. 실제 활용 시나리오
이 패턴은 다음과 같은 상황에서 유용합니다:
7.1 웹 요청 처리
// 여러 API 엔드포인트에서 동시에 데이터 수집
urls := []string{"api1.com", "api2.com", "api3.com", "api4.com"}
for _, url := range urls {
go fetchData(url, resultChannel)
}
7.2 파일 처리
// 여러 파일을 동시에 처리
files := []string{"file1.txt", "file2.txt", "file3.txt", "file4.txt"}
for _, file := range files {
go processFile(file, resultChannel)
}
7.3 데이터베이스 쿼리
// 여러 테이블에서 동시에 데이터 조회
tables := []string{"users", "orders", "products", "categories"}
for _, table := range tables {
go queryTable(table, resultChannel)
}
8. 주의사항과 모범 사례
8.1 고루틴 수 제한
- 너무 많은 고루틴을 동시에 실행하면 시스템 리소스 부족 가능성
- 실제 프로덕션에서는 워커 풀 패턴 사용 권장
8.2 에러 처리
- 현재 코드는 에러 처리가 없습니다
- 실제 사용 시에는 각 고루틴에서 발생할 수 있는 에러를 처리해야 합니다
8.3 컨텍스트 사용
- 긴 작업의 경우
context.Context를 사용하여 취소 기능 추가 권장
9. 결론
이 예제를 통해 Go 언어의 채널과 고루틴을 사용한 동시성 프로그래밍의 핵심 개념을 배웠습니다:
- 채널 타입 변경:
bool에서string으로 변경하여 더 풍부한 정보 전달 - 반복문 활용: 하드코딩된 수신에서 동적 수신으로 개선
- 병렬 성능: 동시 실행으로 전체 처리 시간 단축
- 확장성: 코드 수정 없이 처리할 작업 수 조정 가능
이 패턴은 Go 언어의 "CSP(Communicating Sequential Processes)" 모델을 잘 보여주며, 실제 프로젝트에서 자주 사용되는 중요한 패턴입니다.
'[개발] Go > 중급 프로젝트' 카테고리의 다른 글
| [WebSocket] 채팅방 데모버전 만들어보기 (backend) (2) | 2025.08.26 |
|---|---|
| [URL Checker][New] Go Routine을 장착한 빠른 URL Checker🔥 (1) | 2025.07.14 |
| Channels (0) | 2025.06.27 |
| Goroutines (0) | 2025.06.27 |
| [URL Checker] hitURL 그리고 느린 URL Checker (순차적) (0) | 2025.06.26 |