GO · 고루틴/채널
sync.Cond
sync.Cond로 조건 변수를 구현합니다. 특정 조건이 충족될 때까지 고루틴을 대기시킵니다.
고루틴/채널고급sync-condcondition-variablewaitsignal
핵심 설명
sync.Cond로 조건 변수를 구현합니다. 특정 조건이 충족될 때까지 고루틴을 대기시킵니다.
Go code
package main
import (
"fmt"
"sync"
"time"
)
type Queue struct {
items []int
cond *sync.Cond
}
func NewQueue() *Queue {
return &Queue{cond: sync.NewCond(&sync.Mutex{})}
}
func (q *Queue) Enqueue(item int) {
q.cond.L.Lock()
defer q.cond.L.Unlock()
q.items = append(q.items, item)
q.cond.Signal() // 대기 중인 하나를 깨움
}
func (q *Queue) Dequeue() int {
q.cond.L.Lock()
defer q.cond.L.Unlock()
for len(q.items) == 0 {
q.cond.Wait() // 조건 대기 (잠금 해제 → 대기 → 잠금 획득)
}
item := q.items[0]
q.items = q.items[1:]
return item
}
func main() {
q := NewQueue()
// 소비자
go func() {
for i := 0; i < 5; i++ {
val := q.Dequeue()
fmt.Println("소비:", val)
}
}()
// 생산자
for i := 1; i <= 5; i++ {
time.Sleep(200 * time.Millisecond)
q.Enqueue(i)
fmt.Println("생산:", i)
}
time.Sleep(100 * time.Millisecond)
}학습 팁
Wait()는 반드시 for 루프 안에서 조건을 재확인하며 호출해야 합니다. Spurious wakeup이 발생할 수 있습니다.
주의할 점
Wait()를 if 문으로 감싸면 spurious wakeup 시 조건이 충족되지 않은 상태에서 진행됩니다. 항상 for를 사용하세요.
자주 묻는 질문
sync.Cond란 무엇인가요?
sync.Cond 로 조건 변수를 구현합니다. 특정 조건이 충족될 때까지 고루틴을 대기시킵니다.
sync.Cond 학습 시 주의할 점은 무엇인가요?
Wait() 를 if 문으로 감싸면 spurious wakeup 시 조건이 충족되지 않은 상태에서 진행됩니다. 항상 for 를 사용하세요.