-
go - goroutine개발 2022. 2. 3. 21:44
고루틴 은 go 언어 내부에서 비동기 작업을 효율적으로 처리 할 수 있는 쓰레드 라이브러리다. Go 내부에서 스케줄러에 의해 자체적으로 관리되며 OS 에서 관리하는 경량 쓰레드보다 더 경량이라고 하니 go 언어를 만들면서 쓰레드 작업을 최적화 하는데 많은 심혈을 기울였다고 볼 수 있다. Kotlin의 Coroutine과 비슷하면서도 쓰레드 설정이나 suspend 함수 같은게 없어 간소화된 형태다. Java 에서 쓰레드 문제로 몸살을 겪었다면 go 언어에서는 goroutine을 이용해 간단하게 해결할 수 있다.
사용법
함수 앞에 간단하게 go 만 붙여주면 goroutine 을 사용해서 실행하게 된다.
func bark() { fmt.Println("bark") } func main() { go bark() }
익명의 함수에 대해서도 goroutine으로 실행이 가능하다
func main() { go func() { time.Sleep(time.Second * 2) fmt.Println("async 1") }()
주의사항
일반적인 운영체제에선 자식 쓰레드는 부모 쓰레드가 종료되면 남은 작업 상관 없이 따라서 종료된다. 고루틴도 똑같다. 자식 쓰레드의 작업이 남아 있어도 부모 쓰레드나 프로세스가 종료되면 자식 쓰레드의 남은 작업을 처리하지 못하고 자동 종료 된다. 그래서 코드의 경우 3초 후에 "bark bark"를 출력을 하도록 하지만 실제 출력문에선 main 함수 마지막줄 Done만 출력하게 된다.
func main() { go func() { time.Sleep(time.Second * 3) fmt.Println("bark bark") }() fmt.Println("Done") } # Output Done
GO 언어에서는 자식 고루틴이 얼마나 살아있는 관리 할 수 있는 WaitGroup이라는 라이브러리를 제공한다. Mutex Lock과 사용 용도는 비슷한데 실용성에 초점을 둔 GO 언어 답게 사용 방법은 훨씬 간단하다. 이 라이브러리를 활용하면 자식 쓰레드 종료 시점에 맞춰 부모 쓰레드를 대기시킬 수 있다.
func main() { var waitGroup sync.WaitGroup waitGroup.Add(2) go func() { defer waitGroup.Done() time.Sleep(time.Second * 3) fmt.Println("bark bark") }() go func() { defer waitGroup.Done() time.Sleep(time.Second * 1) fmt.Println("mung mung") }() waitGroup.Wait() fmt.Println("Done") }
위 코드에서 waitGroup 라이브러리의 Add 함수는 대기할 자식 고루틴의 개수를 뜻한다. waitGroup 변수에서 Done() 을 호출하면 waitGroup 내부에서 살아있는 자식 고루틴의 개수를 감소시킨다. 자식 코루틴에서는 종료 시점에 Done 함수를 호출해 자식 코루틴이 종료됐음을 알리면 된다. 위 코드를 보면 두 고루틴에서 defer 키워드를 이용해 종료 시점에 Done 함수를 호출하는 것을 볼 수 있다. 부모 고루틴은 자식 고루틴을 생성하고 waitGroup.Wait()로 대기 모드로 진입한다. 위 코드를 사용하면 고루틴 내부의 로그 메시지가 출력되는 것을 확인 할 수 있다.
mung mung bark bark Done
'개발' 카테고리의 다른 글
kubernetes - Configmap (0) 2022.06.08 Kafka 용어 정리 (0) 2022.05.31 golang 장단점 분석 (vs JAVA) (0) 2022.03.10 Flutter - Row, Column, Flexible, Expanded (0) 2022.03.01 PostgreSQL VACUUM (0) 2022.02.17