💻
프로그래밍
고루틴
Goroutine
Go 언어의 경량 스레드. OS 스레드보다 적은 메모리로 수천 개를 동시 실행 가능. go 키워드로 생성.
Goroutine
Go 언어의 경량 스레드. OS 스레드보다 적은 메모리로 수천 개를 동시 실행 가능. go 키워드로 생성.
고루틴(Goroutine)은 Go 언어에서 제공하는 경량 스레드로, 동시성 프로그래밍의 핵심 요소입니다. OS 스레드가 보통 1MB 이상의 스택을 사용하는 반면, 고루틴은 약 2KB의 스택으로 시작하여 필요에 따라 동적으로 확장됩니다.
고루틴은 go 키워드와 함께 함수 호출을 작성하면 생성됩니다. Go 런타임의 스케줄러가 M:N 스케줄링(M개의 고루틴을 N개의 OS 스레드에 매핑)을 수행하여, 수천에서 수백만 개의 고루틴을 효율적으로 관리합니다.
고루틴 간 통신은 채널(Channel)을 통해 이루어집니다. "공유 메모리로 통신하지 말고, 통신으로 메모리를 공유하라"는 Go의 철학에 따라, 채널을 사용하면 락 없이도 안전한 동시성 코드를 작성할 수 있습니다.
고루틴은 생성 비용이 매우 낮아 서버의 각 요청마다 새 고루틴을 생성하는 패턴이 일반적입니다. 다만 고루틴 누수(leaky goroutine)에 주의해야 하며, context를 사용해 적절히 종료시키는 것이 중요합니다.
package main
import (
"fmt"
"sync"
"time"
)
// 기본 고루틴 생성
func sayHello(name string) {
fmt.Printf("Hello, %s!\n", name)
}
func main() {
// go 키워드로 고루틴 생성
go sayHello("World")
// 채널을 통한 고루틴 간 통신
ch := make(chan int, 3)
// 생산자 고루틴
go func() {
for i := 1; i <= 3; i++ {
ch <- i
fmt.Printf("Sent: %d\n", i)
}
close(ch)
}()
// 소비자 (메인 고루틴)
for num := range ch {
fmt.Printf("Received: %d\n", num)
}
// WaitGroup으로 여러 고루틴 동기화
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
time.Sleep(100 * time.Millisecond)
fmt.Printf("Worker %d done\n", id)
}(i)
}
wg.Wait() // 모든 고루틴 완료 대기
fmt.Println("All workers completed")
}