PHpullh

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 를 사용하세요.

Continue Learning

Go 학습을 이어가세요

총 200개의 독립 HTML 학습 문서 중 하나입니다. 각 문서는 고유 URL과 canonical 메타데이터를 가집니다.