본문 바로가기
golang

[golang] 익명함수를 고루틴으로 실행시킬때의 주의점(순서와 스택)

by devjh 2022. 9. 8.
반응형

이번 게시글에서는 익명함수를 고루틴으로 실행시킬때의 주의점을 정리합니다.

 

1. 소스코드

package main

func main() {
   wg := sync.WaitGroup{}
   for i := 0; i < 5; i++ {
      wg.Add(1)
      go func() {
         defer wg.Done()
         time.Sleep(1)
         fmt.Println("hello ", i)
      }()
   }
   wg.Wait()
}

0부터 4까지 고루틴과 waitgroup을 이용해 hello 1 ~ hello 4 까지 출력시킨 후 프로세스를 종료하려 했으나
결과는 0부터 4가 아닌 5가 5번 출력됩니다.

 

고루틴은 생성되고 실행되기까지 시간이 필요합니다(일반적인 스레드보다는 매우 빠른편)
for문은 5까지 i++가 진행되었고 i < 5의 조건에 부합하지 않아 for문이 종료되었으나,

해당 로직이 진행 된 이후 고루틴이 생성, 실행돼서 나온 결과입니다.

 

2. 올바른 방법

package

func main() {
   wg := sync.WaitGroup{}
   for i := 0; i < 5; i++ {
      wg.Add(1)
      go func(i int) {
         defer wg.Done()
         time.Sleep(1)
         fmt.Println("hello ", i)
      }(i)
   }
   wg.Wait()
}

순서는 보장되지 않습니다

원하는 동작을 하려면 goroutine의 아큐먼트로 for 루프의 변수를 넘겨줘야 합니다.
아규먼트로 고루틴에 변수를 넘겨주면
새로운 스택을 할당해  i의 값을 저장하며, 스택은 네임스페이스가 분리되어있기에 다른 요청과 충돌이 없습니다.

고루틴은 순서가 보장되지 않는다는 특징이 있으므로 순서는 뒤죽박죽이지만 원하는 0,1,2,3,4 의 로직이 모두 실행된 결과입니다.

 

반응형

댓글