Dev/Golang

Goroutine 정리 겸 번역 -1 개념과 구조

puff 2020. 1. 11. 16:13

https://medium.com/a-journey-with-go/go-goroutine-os-thread-and-cpu-management-2f5a5eaf518a

 

 

모 회사 면접에서 Goroutine은 어떻게 동작하냐는 질문에 댕댕이 소리만 했었는데, 좀 정리해서 다음번엔 좀 사람말처럼 들리는 댕댕이소리를 하는것을 목적으로 정리함.

 

예시 코드는 귀찮아서 패스. 

 

1. Goroutine 

Goroutine 은 Go runtime 에 의해 관리되는 경량 쓰레드이다. (#)

 

특징으로는 :

  1. 기본 쓰레드에 비해 엄청 가볍다.
    1. X KB 정도 (기본 쓰레드는 MB단위)
    2. Context Switching 도 가볍다. (program counter 랑 몇개만 들고있을거다.)
  2. 그래서 쉽게쉽게 Concurrency 가능
    1. 쓰레드 위에 몇개 붙어있는 구조임
    2. 따라서 한 쓰레드가 system call같은걸로 block당해도 다른 쓰레드의 goroutine을 돌리면됨
  3. Channel 로 각 goroutine 간 communication.
    1. Communicating sequential processes 라고 함. 대충 공유 메모리 쓰지말고 언어적으로 통신가능 규약같은걸 만들라는 뜻
    2. 다른 동시성 개념으로는 Actor model, thread 뭐 이런게 있다.
      1. 대충 actor 는 채널없이 다이렉트로 각 actor 당 메세지 비동기적으로 던진다는 것
      2. 대충 thread 는 우리가 아는 mutex,lock 뭐 이런거  ->  shared mutable state
    3.  https://en.wikipedia.org/wiki/Communicating_sequential_processes
 

Communicating sequential processes - Wikipedia

In computer science, communicating sequential processes (CSP) is a formal language for describing patterns of interaction in concurrent systems.[1] It is a member of the family of mathematical theories of concurrency known as process algebras, or process c

en.wikipedia.org

 

 

2. Goroutine 구조 기본 ->GMP, MPG..

 

https://medium.com/a-journey-with-go/go-goroutine-os-thread-and-cpu-management-2f5a5eaf518a

  • G - goroutine
  • M - Worker thread, os thread, POSIX thread
  • P - Processor, 기본적으로 Context 같은거임. 자원개념도 더하고
  • 밑에서는 이걸로 줄여쓸거임

 

https://medium.com/a-journey-with-go/go-goroutine-os-thread-and-cpu-management-2f5a5eaf518a 거진 번역급 참조

 

1. 먼저 Processor 들 초기화한다.

https://medium.com/a-journey-with-go/go-goroutine-os-thread-and-cpu-management-2f5a5eaf518a

 

2. G 쓸일이 생기면 idle P 에 os Thread M 물려서 실행

https://medium.com/a-journey-with-go/go-goroutine-os-thread-and-cpu-management-2f5a5eaf518a

 

3. G 들 다 쓰거나 syscall 같은거나 GC 당했거나 한건 P 랑 M 들 다시 idle pool 에 물려놓음

 

https://medium.com/a-journey-with-go/go-goroutine-os-thread-and-cpu-management-2f5a5eaf518a

3. System Calls

System call 은 기본적으로 overhead가 많은 작업이다. Context switching 는 기본적으로 동작해야 되고 protection ring (#), SYSCALL 같은게 있어서 예전보다는 나아졌다고는 해도 안가는게 좋다. 

 

FIle IO같은 blocking syscall 이나, HTTP 같은 non-blocking syscall 같은 거에서 Goroutine이 또 좋은데, 기본적으로 이런 syscall들을 runtime 에서 wrapping 한번 해서 최적화를 하기 때문이다.

 

1. blocking

 

https://medium.com/a-journey-with-go/go-goroutine-os-thread-and-cpu-management-2f5a5eaf518a

 

일단 System call 로 M0이 block 당하면

  1. P를 idle 상태로 넘겨서 기다리다가
  2. M0이 대기가 끝나면 P0을 다시 되찾거나
    1. 안되면 Queue에 넣어 John burr 를 하거나
  3. https://groups.google.com/forum/#!topic/golang-nuts/2IdA34yR8gQ
    1. 이제 또 Goroutine-OS thread 관계가 M:N 이다보니, syscall 이 발생한 M 밑에 다른 G들이 있을수 있는데
    2. 그럴경우 M-G들 따로 떼서 나머지 G들을 계속 돌리는 방법도 씀
    3. 나중에 쓸게많습니다 이주제는.

2. non-blocking

 

https://medium.com/a-journey-with-go/go-goroutine-os-thread-and-cpu-management-2f5a5eaf518a

 

HTTP같은 non-blocking 같은경우에는 thread가 안죽고 (M이 안죽고 해야되는데 어감이 좀...) 그대로 john burr 를 치다가 network poller 에 있는 G를 데려가는 방식임.

 

Goroutine 정리 겸 번역 -2 언제쓸지 모르지만 일단은 기본적으로 이정도만 해도 면접때 했던 댕댕이답변의 1/3 쯤은 사람 목소리로 들릴수도 있겠다...아마......

 

 

참고:

  • https://medium.com/a-journey-with-go
  • https://en.wikipedia.org/wiki/Protection_ring
  • https://tech.ssut.me/goroutine-vs-threads/
  • https://www.usenix.org/system/files/conference/usenixsecurity18/sec18-lipp.pdf 멜트다운 논문인데, OS에서 효율성을 위해 userspace의 일부에 kernel space memory 를 넣는다는 내용이 있었음