Go Scheduler Structure

Created
Created
2020 Dec 6 11:47
Tags
Tags

G, M, P로 구성

  • g - goroutine
  • m - thread
  • p - context
 
notion image

일반

context인 P의 갯수는 GOMAXPROCS 환경 변수로 설정
runtime.GOMAXPROCS() 로 조절 가능
대부분 프로그램을 처음 실행할 때에 이 값을 설정
회색 큐 (runqueues) 로 나타나는 부분은 아직 실행중이지는 않지만 스케쥴될 준비가 되어있는 고루틴 - P(context)에 종속
 
 
 
notion image
Go의 스케쥴러는 계속해서 멈추지 않고 스케쥴링을 할 수 있도록 syscall이 발생한 고루틴을 다른 스레드로 넘겨(hand off) 모든 고루틴이 정상적으로 작동할 수 있도록 보장

syscall이 발생했을 때 (blocking)

이후에 syscall 처리가 끝난 고루틴은 잠시 넘겼던 P(context)를 다시 찾아와서 붙게 되거나 global runqueues 에 들어감 Go의 스케쥴러는 syscall이 발생한 고루틴을 독립적으로 처리하도록 하면서 나머지 context는 다른 스레드(위 이미지에서 M1)로 넘김
실행중인 스레드가 blocking 되었을 때 다른 스레드로 현재 상태(state)를 그대로 넘겨 지속적으로 처리를 할 수 있도록 보장하기 위해 M에 P(context)가 붙는다
P(context)가 구현되었고 이는 GOMAXPROCS값이 1이더라도 Go가 멀티스레드로 동작하는 이유입니다
 
 
과거 Go에는 global runqueues가 있었지만 lock-release 문제로 P마다 own runqueues를 할당하는 방식으로 변경
고루틴의 CS는 다음 시점에서 이루어짐
  • unbuffered 채널에 접근할 때(읽거나 쓸 때)
  • 시스템 I/O가 발생했을 때
  • 메모리가 할당되었을 때
  • time.Sleep() 코드 실행(python asyncio에서 asyncio.sleep()을 이용해 yield하는 것과 유사합니다)
  • runtime.Gosched() 코드 실행
 
 
 

Recommendations