Go routine(고루틴)❓

beluga000·2024년 7월 29일
post-thumbnail

Go Routine

Go Routine(고루틴)은 Go언어의 특징정인 동시성을 가장 잘 느낄 수 있는 Go의 경량 스레드입니다. 고루틴은 Go의 고유한 동시성 모델로, 함수 또는 메서드를 비동기적으로 실행할 수 있도록 해줍니다. 고루틴은 운영 체제의 스레드와는 달리, 훨씬 더 가볍고 적은 리소스를 사용합니다.

Go Routine vs OS Thread

1️⃣ 경량성

Go Routine
매우 가벼운 편으로 고루틴의 초기 스택 크기는 몇 KB에 불과하며, 필요한 경우 동적으로 증가합니다. 또 수천 개의 고루틴을 생성해도 성능에 큰 영향을 미치지 않습니다.

OS Thread
고루틴에 비해 상대적으로 무겁습니다. 초기 스택 크기가 몇 MB로 고정되어 있으며, 많은 수의 스레드를 생성하면 메모리 사용량이 급격히 증가하고 컨텍스트 스위칭 오버헤드가 발생할 수 있습니다.

2️⃣ 스케줄링

Go routine
고루틴은 Go 런타임에 의해 관리되고 스케줄링됩니다. Go 런타임은 여러 고루틴을 하나의 OS 스레드에서 효율적으로 실행할 수 있도록 M:N매핑을 지원합니다. 이는 다수의 고루틴이 소수의 OS 스레드에서 실행될 수 있음을 의미합니다.

OS Thread
고루틴과 다르게 운영 체제 커널에 의해 직접 관리되고 스케줄링됩니다. 각 스레드는 독립적으로 스케줄링되며, 운영 체제는 여러 스레드를 효율적으로 관리하기 위해 다양한 스케줄링 알고리즘을 사용합니다.

3️⃣ 컨텍스트 스위칭

Go Routine
고루틴 간의 컨텍스트 스위칭은 매우 가볍고 빠릅니다. Go 런타임이 사용자 모드에서 수행되기 때문에 오버헤드가 적습니다.

OS Thread
OS 스레드 간의 컨텍스트 스위칭은 비교적 무겁고 느립니다. 커널 모드에서 수행되며, 스레드 로컬 스토리지 및 CPU 레지스터 상태를 저장하고 복구하는 데 시간이 더 걸립니다.

4️⃣ 메모리 사용

Go Routine
고루틴은 메모리를 효율적으로 사용합니다. 초기 스택 크기가 작고 필요한 경우에만 크기가 증가하므로 메모리 낭비가 적습니다.

OS Thread
고정된 크기의 스택을 사용하므로, 메모리 낭비가 발생할 수 있습니다. 많은 수의 스레드를 생성할 경우 메모리 사용량이 급격히 증가합니다.

5️⃣ 동기화 메커니즘

Go Routine
고루틴은 채널과 같은 Go언어의 동기화 메커니즘을 사용합니다. 채널을 통해 고루틴 간에 안전하고 효율적으로 데이터를 주고 받을 수 있습니다.

OS Thread
OS 스레드는 뮤텍스, 세마포어, 조건 변수 등의 전통적인 동기화 메커니즘을 사용합니다. 이러한 메커니즘은 더 복잡하고 오류가 발생하기 쉬울 수 있습니다.

요약해보면 고루틴은 고성능, 확장성 및 간편한 동시성 프로그래밍을 목표로 설계되었습니다. 반면에 OS 스레드는 운영체제의 기본 스레드 모델로, 더 광범위한 언어와 환경에서 사용할 수 있는 일반적인 방법입니다. 각 방법은 특정 상황에서 더 적합할 수 있으며, 사용 목적에 따라 선택하는 것이 중요합니다.

Go Routine 예시

package main

import (
	"fmt"
	"sync"
	"time"
)

// 작업을 수행할 함수
func worker(id int, wg *sync.WaitGroup) {
	defer wg.Done() // 함수가 종료되면 WaitGroup에 완료를 알림
	fmt.Printf("Worker %d starting\n", id)

	// 실제 작업 (여기서는 단순히 1초 대기)
	time.Sleep(time.Second)
	fmt.Printf("Worker %d done\n", id)
}

func main() {
	var wg sync.WaitGroup

	// 5개의 고루틴 생성
	for i := 1; i <= 5; i++ {
		wg.Add(1) // WaitGroup 카운터 증가
		go worker(i, &wg) // 고루틴 생성
	}

	// 모든 고루틴이 완료될 때까지 대기
	wg.Wait()
	fmt.Println("All workers completed")
}

위 코드에서 worker 함수는 고루틴으로 실행될 함수입니다.
wg *sync.WaitGroup 파라미터를 받아 작업이 완료되었음을 알리기 위해 사용합니다.
defer wg.Done()는 함수가 종료될 때 wg.Done()을 호출하여 WaitGroup 카운터를 감소시킵니다.
time.Sleep(time.Second)는 작업을 시뮬레이션하기 위해 1초 동안 대기합니다.

•	var wg sync.WaitGroup을 통해 WaitGroup을 생성합니다.
•	반복문을 통해 5개의 고루틴을 생성하고 각 고루틴을 실행합니다.
•	wg.Add(1)은 WaitGroup 카운터를 증가시켜 고루틴의 시작을 알립니다.
•	go worker(i, &wg)는 고루틴을 생성하고 worker 함수를 실행합니다.
•	wg.Wait()는 모든 고루틴이 완료될 때까지 대기합니다.
•	모든 고루틴이 완료되면 “All workers completed” 메시지를 출력합니다.
profile
Developer

0개의 댓글