포스트

고루틴 goroutine?

Golang은 뛰어난 동시성 지원이 장점이라고들 한다. 일반적으로 쓰레드를 활용하여 동시성 프로그래밍을 하지만, Golang은 고루틴 goroutine으로 가능하다.

고루틴 Goroutine

공시적인 설명으로는 경량 쓰레드이다. 실제 OS의 쓰레드를 사용하는 것이 아닌, golang의 런타임에서 관리되는 논리적 / 가상적 쓰레드이다.

사용법

1
2
3
  go func() {
    // 대충 코드
  }()

이게 끝이다.

thread VS goroutine

  1. 메모리 사용량
    • goroutine: 생성시 약 2KB의 스택 메모리 혹은 힙 메모리 공간만을 사용한다.
    • thread: 약 1MB 의 메모리 공간을 사용한다.
    • P.S. Guard Page: 쓰레드가 사용할 메모리 공간과 각 메모리 간의 경계 역할 - 따라서 스레드 기반의 동시성 처리는 결국 메모리 부족 현상(OutOfMemory) 문제 발생할 수 있으므로, 스레드를 미리 생성해 재활용하는 형태가 될 수 있음.
  2. 비용
    • goroutine: 런타임에서 논리적으로(하드웨어와 상관 없이) 생성되고 소거되기 때문에 가볍다.
    • thread: OS 에 스레드 생성을 요청해 사용하고 작업 완료 시 다시 OS에 반환해야 한다.
    • 따라서 쓰레드 생성시마다 OS에 요청해 생성하고 다시 반환하는 방식이 더 리소스 사용량이 많다.
  3. Context Switching 비용
    • 하나의 스레드가 특정 작업 처리를 위해 사용(Blocking)된다면, 다른 쓰레드가 대신하여 처리하도록 스케쥴링 됨
    • goroutine: 3개의 레지스터(PC(Program Counter)), SP(Stack Pointer), DX)만 save/restore 작업을 함
    • thread: 스레드가 스케쥴링고 교체되는 동안 스케쥴러에서는 모든 레지스터들을 save/restore 해야함
    • 일반적으로 16개의 범용 레지스터, PC, SP, Segment 레지스터, 16개의 XMM레지스터, FP coprocessor state, 16개의 AVX 레지스터, 모든 MSR들 등 save/restore 작업을 진해해야함 - 따라서 Context Switching 할 때 save/restore 해야하는 레지스터의 개수부터가 큰 차이가 남

결론

golang이 메모리 사용량과 쓰레드 생성과 작업처리에 있어서의 비용 측면에서 훨씬 효율적이다.

마지막

goroutine의 동작 방식과 쓰레드 종류에 대해선 다음에 서술하고자 한다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.