본문 바로가기
golang

[golang] 고루틴(go routine)이란

by devjh 2021. 11. 15.
반응형

이번 게시글에서는 고루틴에 대해 정리합니다.

 

1. 고루틴이란

고루틴은 동시에 여러 로직을 병렬적으로 진행시키고 싶을때 사용합니다.

일반적인 프로그래밍 언어에서 사용하는 스레드(그린스레드)들은 생성하는데 1MB가 필요하고, 커널레벨 스레드와 연결되어 운영체제한테 스레드를 위임해 스케줄링 받아 돌아가는 방식이지만

고루틴은 2KB만 필요하며 커널에서 직접 스케줄링 받지 않고 고 스케줄러가 직접 스케줄링해주므로 훨씬 가볍고 빠릅니다.

 

사용법은 메서드 앞에 go 라는 키워드만 붙여주면 됩니다.

2. 예제

package main

import (
	"fmt"
	"runtime"
	"time"
)

func main() {
        // 현재 main문을 실행시키는 고루틴인 1이 출력됩니다.
	fmt.Println("Goroutines 갯수: ", runtime.NumGoroutine()) 

	go func() {
		for i := 0; i < 3; i++ {
			fmt.Println("goroutine!!")
			time.Sleep(time.Second)
		}
		fmt.Println("goroutine finish!!")
	}()
    
        // main문과 go루틴을 만들었으니 2가 찍힙니다.
	fmt.Println("Goroutines 갯수: ", runtime.NumGoroutine()) 

	// 아래의 로직이 없으면 고루틴보다 메인루틴이 먼저끝나고 goroutine!!!!!! 은 출력되지 않습니다.
	// 고루틴은 운영체제가 직접 관리하지 않습니다.
	for i := 0; i < 4; i++ {
		fmt.Println("main routine!!")
		time.Sleep(time.Second)
	}
	fmt.Println("main routine finish!!")
}

 

병렬적으로 실행하고싶은 메서드 앞에 go 키워드만 붙여주면 고루틴이 돌아갑니다.

 

2. 고루틴은 다른 언어의 스레드풀처럼 동작한다?

스레드풀은 스레드의 생성과 소멸시간을 단축하기위해 미리 동시성 작업을 할 준비를 끝내놓은 공간을 말합니다.

커널레벨 스레드와 연결해주는 방식도 일반 유저레벨 스레드와 다르고, 우선순위도 낮습니다

(주로 논블락, 비동기 작업에 사용됩니다.)

또한 스레드풀은 프로세스가 끝나면 스레드풀에 작업이 남아있더라도 프로세스가 해당 스레드들을 종료해버립니다.

고루틴도 메인스레드가 끝나면 커널레벨 스레드에 위임하지 않는것처럼 끝나버리는 특징이 있으나

고루틴은 처음부터 고 스케줄러가 관리하고 os에게 고루틴을 위임하지 않습니다.

 

3. 고루틴과 코어

고루틴은 커널레벨 스레드로 직접 매핑시키는 방식이 아니다보니 직접 사용할 코어 갯수를 지정할수도 있습니다.

go버전마다 상이하지만(낮은버전에서는 코어를 1개만 사용하도록 설정되어있습니다.)

최근의 버전들은 모든코어를 사용하도록 설정되어 있습니다.

package main

import (
	"fmt"
	"runtime"
)

func main() {
	fmt.Println("내 컴퓨터의 코어 갯수: ", runtime.NumCPU())
	fmt.Println("고루틴이 사용하는 코어 갯수: ", runtime.GOMAXPROCS(0))
}

runtime.GOMAXPROCS 에 아규먼트로 0을 넘기면 현재 사용하는 코어의 갯수를 확인할 수 있으며

원하는 숫자를 넘기면 고루틴이 사용할 코어의 갯수를 설정할 수 있습니다.

 

우선순위가 낮은 고루틴이 많이 생성되는 애플리케이션의 경우 사용하는 코어수를 제한하여 서버의 자원을 효율적으로 사용할 수 있습니다. 

 

 

반응형

댓글