구글 go 언어를 공부하면서 몇몇 중요 포인트를 메모중입니다. (5/N)
By SeukWon Kang
오랫만에 다시 go 이야깁니다.
오랬만에 기억을 되살리기 위해 이런 저런 이야기를 잠깐 해보면 go 언어의 특징중 가장 두드러지는 것을 하나 들면 goroutine을 들 수 있을 텐데요.
많은 서버와 대용량의 데이터(소위 big data)를 처리 하고 있는 구글은 이를 위해서 여러 언어를 사용하고 있다고 알려져 있습니다. 하지만 각각의 언어들은 장단점이 있는 관계로 구미에 딱 맞는 언어가 필요하여 go 언어를 만들었다는 게 사람들의 짐작 입니다.
그래서 go 언어에는 구글이 가장 필요로 하는 goroutine 과 channel 이 기본으로 존재합니다. (고 생각합니다. ^^; )
이후 요약 입니다.
goroutine 일종의 micro thread 어떻게 보면 stackless python이나 ugreen 같은 것 . ( 역시 대세 인가? )
자연스러운 coroutine 지원을 위해 go 언어는 기본적으로 goroutine 과 channel을 지원하는데 이는 언어 뿐만 아니라 컴파일러 그리고 runtime 의 지원을 통해서 이루어 진다.
현재의 go 구현은 기본적으로는 cpu를 1개만 사용하게 설정되어 있기 때문에 시스템의 모든 cpu를 사용하고 싶다면 runtime.GOMAXPROCS(runtime.NumCPU()) 같은 코드를 추가해야 한다. (이왕이면 init() 에 넣으면 좋다. )
그리고 go 언어가 지원하는 gabage collection 역시 concurrent programming을 위해 꼭필요한 요소이다. shared memory 로 통신 하지 말고 channel을 사용할것.
goroutine go goroutinename() 형태로 실행 concurrent 실행 최소 4k 의 segmented stack , very cheap , but not free
return 또는 runtime.Goexit() 로 종료.
channel goroutine간의 communication을 위한 typed data buffer , 그리고 first class ch <- : channel에 넣음 ( 로 보냄 ) <-ch : channel에서 꺼냄 ( 에서 받음 ) 형태로 사용 ch := make( chan int , 1 ) : 버퍼 크기 1짜리 생성. 크기가 0이면 synchronous channel , 1이상이면 asynchronous 로 작동.
chan<- : 쓰기 전용 channel type select { case writeCh <- data: default: } 형태로 사용하면 non block channel write 가 가능.
<-chan : 읽기 전용 channel type d, ok := <-readCh 형태로 nonblock read 가능
쓰기가 가능한 channel은 close(ch) 가 가능하다.
channel factory pattern goroutine에 channel을 인자로 주는 것이아니고 함수가 goroutine을 (lambda 형태로) 실행하고 동시에 그 goroutine이 사용할 channel을 만들어 return 하는 형태.
range를 사용해 for문에 사용가능 for i := range ch { } channel이 close 될때까지 반복한다.
select 여러개의 channel을 상대로 준비된 channel을 실행하거나 준비된 chennel이 없고 default가 있는경우 default를 실행 , 없는 경우 wait를 한다.
정기적으로 action을 해야 하는 경우 time.NewTicker( repeatDur ) 라이브러리 함수를 사용. 처리 량을 throttling 하고 싶은 경우는 time.Tick( dur ) 사용. 한번만 (timeout 용 ) 인 경우는 time.After( ) 를 사용.