모 회사 면접에서 Goroutine은 어떻게 동작하냐는 질문에 댕댕이 소리만 했었는데, 좀 정리해서 다음번엔 좀 사람말처럼 들리는 댕댕이소리를 하는것을 목적으로 정리함.
예시 코드는 귀찮아서 패스.
1. Goroutine
Goroutine 은 Go runtime 에 의해 관리되는 경량 쓰레드이다. (#)
특징으로는 :
- 기본 쓰레드에 비해 엄청 가볍다.
- X KB 정도 (기본 쓰레드는 MB단위)
- Context Switching 도 가볍다. (program counter 랑 몇개만 들고있을거다.)
- 그래서 쉽게쉽게 Concurrency 가능
- 쓰레드 위에 몇개 붙어있는 구조임
- 따라서 한 쓰레드가 system call같은걸로 block당해도 다른 쓰레드의 goroutine을 돌리면됨
- Channel 로 각 goroutine 간 communication.
- Communicating sequential processes 라고 함. 대충 공유 메모리 쓰지말고 언어적으로 통신가능 규약같은걸 만들라는 뜻
- 다른 동시성 개념으로는 Actor model, thread 뭐 이런게 있다.
- 대충 actor 는 채널없이 다이렉트로 각 actor 당 메세지 비동기적으로 던진다는 것
- 대충 thread 는 우리가 아는 mutex,lock 뭐 이런거 -> shared mutable state
- https://en.wikipedia.org/wiki/Communicating_sequential_processes
2. Goroutine 구조 기본 ->GMP, MPG..
- 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 들 초기화한다.
2. G 쓸일이 생기면 idle P 에 os Thread M 물려서 실행
3. G 들 다 쓰거나 syscall 같은거나 GC 당했거나 한건 P 랑 M 들 다시 idle pool 에 물려놓음
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
일단 System call 로 M0이 block 당하면
- P를 idle 상태로 넘겨서 기다리다가
- M0이 대기가 끝나면 P0을 다시 되찾거나
- 안되면 Queue에 넣어 John burr 를 하거나
- https://groups.google.com/forum/#!topic/golang-nuts/2IdA34yR8gQ
- 이제 또 Goroutine-OS thread 관계가 M:N 이다보니, syscall 이 발생한 M 밑에 다른 G들이 있을수 있는데
- 그럴경우 M-G들 따로 떼서 나머지 G들을 계속 돌리는 방법도 씀
- 나중에 쓸게많습니다 이주제는.
2. non-blocking
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 를 넣는다는 내용이 있었음
'Dev > Golang' 카테고리의 다른 글
Go 1.14 출시 (0) | 2020.02.27 |
---|