PHpullh
학습 라이브러리/Go/채널 — 고루틴 통신

GO · 고루틴/채널

채널 — 고루틴 통신

"메모리를 공유해서 통신하지 말고, 통신을 통해 메모리를 공유하라" — Go 격언.

고루틴/채널중급channel채널bufferedselectclose

핵심 설명

"메모리를 공유해서 통신하지 말고, 통신을 통해 메모리를 공유하라" — Go 격언.

Go code

package main

import (
	"fmt"
	"time"
)

func producer(ch chan<- int, n int) {
	for i := 0; i < n; i++ {
		ch <- i
		time.Sleep(50 * time.Millisecond)
	}
	close(ch) // 완료 시 채널 닫기
}

func main() {
	// Unbuffered channel — 동기적
	ch1 := make(chan int)
	go func() { ch1 <- 42 }()
	fmt.Println(<-ch1) // 42

	// Buffered channel — 비동기
	ch2 := make(chan string, 3)
	ch2 <- "a"
	ch2 <- "b"
	ch2 <- "c"
	fmt.Println(<-ch2, <-ch2, <-ch2)

	// for range로 채널 소비
	numCh := make(chan int, 10)
	go producer(numCh, 5)
	for n := range numCh {
		fmt.Printf("받음: %d
", n)
	}

	// select — 여러 채널 대기
	ch3 := make(chan string)
	ch4 := make(chan string)

	go func() { time.Sleep(100*time.Millisecond); ch3 <- "ch3" }()
	go func() { time.Sleep(200*time.Millisecond); ch4 <- "ch4" }()

	for i := 0; i < 2; i++ {
		select {
		case msg := <-ch3:
			fmt.Println("받음:", msg)
		case msg := <-ch4:
			fmt.Println("받음:", msg)
		case <-time.After(500 * time.Millisecond):
			fmt.Println("타임아웃")
		}
	}

	// Done 채널 패턴
	done := make(chan struct{})
	go func() {
		fmt.Println("백그라운드 작업")
		close(done)
	}()
	<-done
}

학습 팁

close(ch)는 보내는 쪽에서만 호출하세요. 닫힌 채널에서 받으면 zero value와 false를 반환합니다. 닫힌 채널에 보내면 패닉입니다.

주의할 점

닫힌 채널에 전송(ch )하면 패닉입니다. 채널 닫기는 전송 측에서 한 번만 수행하세요.

자주 묻는 질문

채널 — 고루틴 통신란 무엇인가요?

"메모리를 공유해서 통신하지 말고, 통신을 통해 메모리를 공유하라" — Go 격언.

채널 — 고루틴 통신 학습 시 주의할 점은 무엇인가요?

닫힌 채널에 전송( ch )하면 패닉입니다. 채널 닫기는 전송 측에서 한 번만 수행하세요.