GO · 고루틴/채널
고루틴 & WaitGroup
Go의 경량 스레드인 고루틴과 동기화 도구 WaitGroup으로 병렬 처리를 구현합니다.
고루틴/채널중급goroutineWaitGroupMutexRWMutexsync
핵심 설명
Go의 경량 스레드인 고루틴과 동기화 도구 WaitGroup으로 병렬 처리를 구현합니다.
Go code
package main
import (
"fmt"
"sync"
"time"
)
func worker(id int, wg *sync.WaitGroup) {
defer wg.Done() // 완료 시 카운터 감소
fmt.Printf("worker %d 시작
", id)
time.Sleep(time.Duration(id) * 100 * time.Millisecond)
fmt.Printf("worker %d 완료
", id)
}
// Mutex로 경쟁 조건 방지
type SafeCounter struct {
mu sync.Mutex
v map[string]int
}
func (c *SafeCounter) Inc(key string) {
c.mu.Lock()
defer c.mu.Unlock()
c.v[key]++
}
func (c *SafeCounter) Value(key string) int {
c.mu.Lock()
defer c.mu.Unlock()
return c.v[key]
}
func main() {
// WaitGroup 기본 패턴
var wg sync.WaitGroup
for i := 1; i <= 5; i++ {
wg.Add(1)
go worker(i, &wg)
}
wg.Wait()
fmt.Println("모든 worker 완료")
// RWMutex — 읽기는 동시, 쓰기는 독점
var rwmu sync.RWMutex
data := make(map[string]string)
// 쓰기
rwmu.Lock()
data["key"] = "value"
rwmu.Unlock()
// 읽기 (여러 고루틴 동시 가능)
rwmu.RLock()
fmt.Println(data["key"])
rwmu.RUnlock()
// SafeCounter 사용
counter := SafeCounter{v: make(map[string]int)}
for i := 0; i < 100; i++ {
go counter.Inc("key")
}
time.Sleep(100 * time.Millisecond)
fmt.Println("카운트:", counter.Value("key"))
}학습 팁
go run -race main.go로 race condition을 감지할 수 있습니다. 개발 중에 습관적으로 실행하세요.
주의할 점
wg.Add(1)은 고루틴 시작 전에 호출해야 합니다. 고루틴 내부에서 호출하면 WaitGroup이 이미 0이 될 수 있습니다.
자주 묻는 질문
고루틴 & WaitGroup란 무엇인가요?
Go의 경량 스레드인 고루틴과 동기화 도구 WaitGroup으로 병렬 처리를 구현합니다.
고루틴 & WaitGroup 학습 시 주의할 점은 무엇인가요?
wg.Add(1) 은 고루틴 시작 전에 호출해야 합니다. 고루틴 내부에서 호출하면 WaitGroup이 이미 0이 될 수 있습니다.
Continue Learning
Go 학습을 이어가세요
총 200개의 독립 HTML 학습 문서 중 하나입니다. 각 문서는 고유 URL과 canonical 메타데이터를 가집니다.