Go 스케줄링
고루틴 : Go의 최소 실행 단위로, main도 profile도 모든 게 다 고루틴
고의 동시성에서는 Go 스케줄러로 어떻게 효율적으로 관리하느냐에 크게 의존합니다.

- goroutine 생성
새로운 작업(Goroutine, G)이 생성되면, 해당 작업은 현재 P(processor)의 LRQ에 삽입됩니다.
P는 자신만의 LRQ(Local Run Queue)를 보유하며 P의 개수는 GOMAXPROCS로 결정됩니다.
이거로 동시 실행이 가능한 goroutine 수를 제한합니다. - 로컬 처리
P는 자신의 LRQ에 있는 작업을 우선 실행하는 데 이 과정은 빠르고 효율적이며, 락 경합 없이 처리됩니다. - 글로벌 작업 분배
만약 한 P의 LRQ가 비거나 작업이 부족하면, 해당 P는 다른 P의 LRQ에서 작업을 훔치거나 GRQ(Global Run Queue)에서 작업을 가져옵니다. 반대로, LRQ가 가득 차면 추가 작업은 GRQ로 보내져 전체 시스템에 분산됩니다.
GRQ로 LRQ에게 작업을 저장과 분배 및 재분배를 하여 작업이 몰리는 걸 방지합니다. - 실행
실제 실행은 M(OS 스레드)에 의해 이루어지며, P가 M(Machine)에 할당되어 G(Goroutine)를 실행하는 방식으로 진행됩니다. - 채널 처리
blokcing goroutines는 대기 상태의 고루틴들로 채널을 처리하게 됩니다, 채널에서 신호가 오면 그때 실행되죠.
정리
- PMG 모델 (G, M, P)
goroutine, OS 스레드, 그리고 스케줄링 단위인 P를 통해 작업을 분배하는 핵심 구조 - Local Run Queue (LRQ)
각 P가 자신만의 빠른 실행 큐를 가지며, 작업을 로컬에서 신속하게 처리 - Global Run Queue (GRQ)
모든 P가 공유하는 큐로, 작업 부하의 균형을 맞추고, LRQ가 비었을 때 작업을 보충
동시성이란
Go에서의 동시성을 설명하기에 앞서서 동시성이란 무엇이고 병렬성이랑 뭐가 다른지 확인해 봅시다.
- 병렬성 : 실제로 물리적으로 같은 시간에 계산되는 물리적 동시성
- 동시성 : 같이 실행될 거라는 논리적 동시성
이를 코드와 프로그램에 적용하면 아래와 같습니다.
동시성은 코드로 알 수 있는 것이고 병렬성은 실제 연산을 통해서 알 수 있다.
위 개념으로 아래 3가지 개념을 알 수 있습니다.
- 우리는 병렬적으로 실행될 거라 생각하며 동시성을 지닌 코드를 짠다.
- 멀티 코어 환경에서 코드를 짜더라도 진짜 병렬로 실행되는지 알기 어렵다. (플랫폼, CPU를 통해야 함)
- 그렇기에 병렬처리 여부는 컨텍스트(작업)의 의해 결정된다.
컨텍스트(Context)
컨텍스트는 동시성 환경에서 실행 중인 프로세스나 스레드, 혹은 작업의 정보와 설정을 담는 작업 단위입니다. 위에서 언급한 병렬처리는 컨텍스트와 관련되었단 말은 실행 컨텍스트를 의미합니다.
이 실행 컨텍스트가 시분할 시스템에서 어떻게 적용되는지는 아래와 같습니다.
쓰레드로 병렬 처리하기 위해 작업 컨텍스트의 정보를 사용한다고 보시면 됩니다.

이전 포스팅에서 Context 활용법을 알 수 있습니다.
https://seung.tistory.com/entry/GoLang-Context%EA%B0%80-%EB%AD%98%EA%B9%8C%EC%9A%94
[GoLang] Context가 뭘까요?
최근 면접에서 Go의 Context가 뭐냐고 물으셨다. 가장 중요할 때 기억나지 않는 게 세상의 규칙인 게 분명했다.. Context 정의 context 패키지에서 제공하는 걸로 작업 명세서다. "10시부터 12시는 네가
seung.tistory.com
고루틴, 채널, 뮤텍스
GoLang(Go)은 OS의 스레드를 제공하는 타 언어(몇몇)와 다르게 별도로 추상화한 쓰레드를 제공합니다.
그 핵심은 기능은 고루틴과 채널이 있습니다.
- 고루틴 (Goroutine)
- 고루틴은 경량 스레드로, OS 스레드에서 한번 더 추상화된 스레드, 수백만 개의 고루틴도 쉽게 관리 가능
- 타 언어는 스레드나 프로세스로 생성하지만 고는 고루틴으로 훨씬 가볍게 동시성 사용
- 고의 런타임은 고루틴을 OS 스레드에 자동으로 다중화하여 스케줄링해 줌
- 8GB 램이 있다고 가정을 하면 이론상 스와핑 없이도 수백만 개의 고루틴을 돌릴 수 있다
- OS 수준에서의 컨텍스트 스위칭보다 압도적인 효율을 가진 소프트웨어적 컨텍스트 스위칭
- 채널 (Channel)
- 고루틴 간의 통신을 담당
- 타 언어는 뮤텍스(Lock/Unlock)나 세마포어로 메모리를 동기화하지만 고는 이를 채널로 대신할 수 있다
- 채널을 사용함으로써 메모리 동기화 방식보다 훨씬 쉽게 구현
하지만 항상 채널을 사용하는 게 옳지는 않습니다. 성능의 이유로 상황에 따라 뮤텍스를 사용하는 게 좋을 수 있습니다.
그 상황은 아래 결정 트리를 따라가면 알 수 있습니다.
상황에 따라 기본 요소인 뮤텍스나 채널을 사용하면 됩니다.

CSP
Go에서 동시성을 설명할 때 핵심 키워드는 CSP입니다.
이는 위에서 채널로 설명한 특징으로
CSP(Communicating Sequential Processes Style)로 타 언어의 락(Lock) 기반 모델과 다르게 채널과 고루틴으로 동시성 모델을 간단하게 구현할 수 있다.
지금 공부중인 책에서는 Go의 철학을 다음과 같이 정리했습니다.
단순화를 목표로하고 가능하면 채널을 사용하며, 고루틴을 무한정 쓸 수 있는 자원처럼 사용해라
'Go Lang > Study' 카테고리의 다른 글
[GoLang] GoLang 면접 질문 정리 (2) | 2024.02.26 |
---|---|
[GoLang] 반복문에서 고루틴 돌릴 때 주의점 (0) | 2024.01.19 |
[GoLang] 데드락, 라이브락, 기아상태 이해하기 (Deadlock, Livelock, Starvation) (1) | 2024.01.02 |
[GoLang] Context가 뭘까요? (2) | 2023.12.02 |
[GoLang] Markdown을 HTML로 변환하기 (고도화) (0) | 2023.11.12 |
Go 스케줄링
고루틴 : Go의 최소 실행 단위로, main도 profile도 모든 게 다 고루틴
고의 동시성에서는 Go 스케줄러로 어떻게 효율적으로 관리하느냐에 크게 의존합니다.

- goroutine 생성
새로운 작업(Goroutine, G)이 생성되면, 해당 작업은 현재 P(processor)의 LRQ에 삽입됩니다.
P는 자신만의 LRQ(Local Run Queue)를 보유하며 P의 개수는 GOMAXPROCS로 결정됩니다.
이거로 동시 실행이 가능한 goroutine 수를 제한합니다. - 로컬 처리
P는 자신의 LRQ에 있는 작업을 우선 실행하는 데 이 과정은 빠르고 효율적이며, 락 경합 없이 처리됩니다. - 글로벌 작업 분배
만약 한 P의 LRQ가 비거나 작업이 부족하면, 해당 P는 다른 P의 LRQ에서 작업을 훔치거나 GRQ(Global Run Queue)에서 작업을 가져옵니다. 반대로, LRQ가 가득 차면 추가 작업은 GRQ로 보내져 전체 시스템에 분산됩니다.
GRQ로 LRQ에게 작업을 저장과 분배 및 재분배를 하여 작업이 몰리는 걸 방지합니다. - 실행
실제 실행은 M(OS 스레드)에 의해 이루어지며, P가 M(Machine)에 할당되어 G(Goroutine)를 실행하는 방식으로 진행됩니다. - 채널 처리
blokcing goroutines는 대기 상태의 고루틴들로 채널을 처리하게 됩니다, 채널에서 신호가 오면 그때 실행되죠.
정리
- PMG 모델 (G, M, P)
goroutine, OS 스레드, 그리고 스케줄링 단위인 P를 통해 작업을 분배하는 핵심 구조 - Local Run Queue (LRQ)
각 P가 자신만의 빠른 실행 큐를 가지며, 작업을 로컬에서 신속하게 처리 - Global Run Queue (GRQ)
모든 P가 공유하는 큐로, 작업 부하의 균형을 맞추고, LRQ가 비었을 때 작업을 보충
동시성이란
Go에서의 동시성을 설명하기에 앞서서 동시성이란 무엇이고 병렬성이랑 뭐가 다른지 확인해 봅시다.
- 병렬성 : 실제로 물리적으로 같은 시간에 계산되는 물리적 동시성
- 동시성 : 같이 실행될 거라는 논리적 동시성
이를 코드와 프로그램에 적용하면 아래와 같습니다.
동시성은 코드로 알 수 있는 것이고 병렬성은 실제 연산을 통해서 알 수 있다.
위 개념으로 아래 3가지 개념을 알 수 있습니다.
- 우리는 병렬적으로 실행될 거라 생각하며 동시성을 지닌 코드를 짠다.
- 멀티 코어 환경에서 코드를 짜더라도 진짜 병렬로 실행되는지 알기 어렵다. (플랫폼, CPU를 통해야 함)
- 그렇기에 병렬처리 여부는 컨텍스트(작업)의 의해 결정된다.
컨텍스트(Context)
컨텍스트는 동시성 환경에서 실행 중인 프로세스나 스레드, 혹은 작업의 정보와 설정을 담는 작업 단위입니다. 위에서 언급한 병렬처리는 컨텍스트와 관련되었단 말은 실행 컨텍스트를 의미합니다.
이 실행 컨텍스트가 시분할 시스템에서 어떻게 적용되는지는 아래와 같습니다.
쓰레드로 병렬 처리하기 위해 작업 컨텍스트의 정보를 사용한다고 보시면 됩니다.

이전 포스팅에서 Context 활용법을 알 수 있습니다.
https://seung.tistory.com/entry/GoLang-Context%EA%B0%80-%EB%AD%98%EA%B9%8C%EC%9A%94
[GoLang] Context가 뭘까요?
최근 면접에서 Go의 Context가 뭐냐고 물으셨다. 가장 중요할 때 기억나지 않는 게 세상의 규칙인 게 분명했다.. Context 정의 context 패키지에서 제공하는 걸로 작업 명세서다. "10시부터 12시는 네가
seung.tistory.com
고루틴, 채널, 뮤텍스
GoLang(Go)은 OS의 스레드를 제공하는 타 언어(몇몇)와 다르게 별도로 추상화한 쓰레드를 제공합니다.
그 핵심은 기능은 고루틴과 채널이 있습니다.
- 고루틴 (Goroutine)
- 고루틴은 경량 스레드로, OS 스레드에서 한번 더 추상화된 스레드, 수백만 개의 고루틴도 쉽게 관리 가능
- 타 언어는 스레드나 프로세스로 생성하지만 고는 고루틴으로 훨씬 가볍게 동시성 사용
- 고의 런타임은 고루틴을 OS 스레드에 자동으로 다중화하여 스케줄링해 줌
- 8GB 램이 있다고 가정을 하면 이론상 스와핑 없이도 수백만 개의 고루틴을 돌릴 수 있다
- OS 수준에서의 컨텍스트 스위칭보다 압도적인 효율을 가진 소프트웨어적 컨텍스트 스위칭
- 채널 (Channel)
- 고루틴 간의 통신을 담당
- 타 언어는 뮤텍스(Lock/Unlock)나 세마포어로 메모리를 동기화하지만 고는 이를 채널로 대신할 수 있다
- 채널을 사용함으로써 메모리 동기화 방식보다 훨씬 쉽게 구현
하지만 항상 채널을 사용하는 게 옳지는 않습니다. 성능의 이유로 상황에 따라 뮤텍스를 사용하는 게 좋을 수 있습니다.
그 상황은 아래 결정 트리를 따라가면 알 수 있습니다.
상황에 따라 기본 요소인 뮤텍스나 채널을 사용하면 됩니다.

CSP
Go에서 동시성을 설명할 때 핵심 키워드는 CSP입니다.
이는 위에서 채널로 설명한 특징으로
CSP(Communicating Sequential Processes Style)로 타 언어의 락(Lock) 기반 모델과 다르게 채널과 고루틴으로 동시성 모델을 간단하게 구현할 수 있다.
지금 공부중인 책에서는 Go의 철학을 다음과 같이 정리했습니다.
단순화를 목표로하고 가능하면 채널을 사용하며, 고루틴을 무한정 쓸 수 있는 자원처럼 사용해라
'Go Lang > Study' 카테고리의 다른 글
[GoLang] GoLang 면접 질문 정리 (2) | 2024.02.26 |
---|---|
[GoLang] 반복문에서 고루틴 돌릴 때 주의점 (0) | 2024.01.19 |
[GoLang] 데드락, 라이브락, 기아상태 이해하기 (Deadlock, Livelock, Starvation) (1) | 2024.01.02 |
[GoLang] Context가 뭘까요? (2) | 2023.12.02 |
[GoLang] Markdown을 HTML로 변환하기 (고도화) (0) | 2023.11.12 |