최근 고루틴에 대해 깊이 이해하고 사용하고 싶은 욕심이 있어 캐서린 콕스 부데이가 짓고 O'Reilly에서 출판한 Concurrency in Go 책을 읽으며 공부하고 있다. 하지만 어느 정도 용어에 대한 지식이 필요한 듯해 보이고 나는 아직은 그 정도 내공을 갖추지 못한 듯하다. 그렇기에 이렇게 블로그에 기록하며 공부하려 한다.
기존의 게시물에서는 고루틴을 사용하는 방법을 알아봤다면 이 게시물에서는 보다 풍부하게 사용하기 위한 원리를 함께 알아보고자 한다.
고루틴
간단한 고루틴을 사용하는 예시 코드를 보겠다.
코드
package main
import (
"fmt"
)
func main() {
go sayHello()
}
func sayHello() {
fmt.Println("hello")
}
결과
고루틴은 실행되지 않는다.
sayHello 함수를 실행하는 고루틴은 실행할 기회조차 얻지 못한다.
sayHello 고루틴에 분기할 시간도 없이 메인 고루틴이 종료가 되기 때문이다.
그렇다면 어떻게 해야 sayHello 함수를 실행할 수 있을까?
가장 간단한 방법은 time.Sleep 함수를 통해 main을 늦게 죽이는 방법이 있지만 이 방법은 프로젝트에서 고루틴을 사용할 때는 단지 다른 고루틴이 실행될 확률을 높일 뿐 정확한 해결법이라 할 수 없다.
우리는 합류지점을 정해 주어야 한다.
Go는 fork-join 모델이라는 동시성 모델을 따른다. fork는 OS를 공부한 사람이라면 어렴풋이라도 알고 있을 용어이다.
(자식 분기를 만들어 부모와 동시에 실행할 수 있다고 이해하면 될 듯하다. 자세한 건 다른 게시물에서 다루겠다.)
그리고 join. 자식 분기가 다시 부모 분기와 합쳐지는 것을 말한다. 그리고 합류지점이라는 것은 두 분기가 합쳐지는 지점이다.
그렇다면 합류지점을 정해준 코드를 살펴보자.
코드
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup
func main() {
wg.Add(1)
go sayHello()
wg.Wait() // 합류지점
}
func sayHello() {
defer wg.Done()
fmt.Println("hello")
}
결과
hello
바라던 결과가 출력된 것을 확인할 수 있다.
이 waitGroup 또한 이다음 게시물을 통해 깊게 알아보겠다.
'Study > Go' 카테고리의 다른 글
[Go] 고루틴(GoRoutine) 심화(3) - sync.Pool (0) | 2022.05.13 |
---|---|
[Go] 고루틴(GoRoutine) 심화(2) - 클로저 함수, 메모리 (0) | 2022.04.28 |
[Go] Go에서 DI는(1) - DI란? (0) | 2022.04.09 |
[Go] Go의 메모리 할당 (0) | 2022.04.08 |
[Go] Heap 자료구조를 사용하는 우선순위 큐 (Priority Queue) (0) | 2021.10.04 |