Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

Code Habit

Go ) 클로저와 고루틴 본문

카테고리 없음

Go ) 클로저와 고루틴

코드베어 2020. 6. 9. 08:17

함수 안에서 클로저를 정의한 뒤 고루틴으로 실행할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package main
 
import (
    "fmt"
    "runtime"
)
 
func main() {
    runtime.GOMAXPROCS(1// 사용할 CPU 개수 1 설정
    
    s := "Hello world !"
 
    for i := 0; i < 100; i++ {
        go func(n int) {        // 익명 함수를 고루틴으로 실행(클로저)
           fmt.Println(s, n)   // s와 매개변수로 받은 n 값 출력
        }(i)                    // 반복문의 변수는 매개변수로 넘겨줌
    }
 
    fmt.Scanln() // main 함수가 종료되지 않도록 대기
}
 
// 실행 결과
Hello, world ! 0
Hello, world ! 1
Hello, world ! 2
...
Hello, world ! 97
Hello, world ! 98
Hello, world ! 99 

일반 클로저는 반복문 안에서 순서대로 실행되지만 고루틴으로 실행한 클로저는 반복문이 끝난 뒤에 고루틴으로 실행된다. 만약 매개변수로 i 를 넘기지 않고 그대로 사용했다면 결과는 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package main
 
import (
    "fmt"
    "runtime"
)
 
func main() {
    runtime.GOMAXPROCS(1// 사용할 CPU 개수 1 설정
    
    s := "Hello, world!"    
 
    for i := 0; i < 100; i++ {
       go func() {
            fmt.Println(s, i)    // 반복문 변수를 클로저에서 바로 출력 
        }()                    
    }
 
    fmt.Scanln() // main 함수가 종료되지 않도록 대기
}
 
// 실행 결과
Hello, world ! 100
Hello, world ! 100
Hello, world ! 100
...
Hello, world ! 100
Hello, world ! 100
Hello, world ! 100 

 

고루틴은 반복문이 완전히 끝난 다음에 생성되므로 고루틴이 생성된 시점의 변수 i의 값은 100이다. 물론 CPU 코어를 하나만 사용했을 때의 상황이다. CPU 코어를 여러 개 사용하면 결과는 조금 달라지지만 의도했던대로 0부터 99까지 빠짐없이 출력되지는 않는다. 

 

클로저를 고루틴으로 실행할 때 반복문에 의해 바뀌는 변수는 반드시 매개변수로 넘겨준다. 즉 매개변수로 넘겨주는 시점에 해당 변수의 값이 복사되므로 고루틴이 생성될 때 그대로 사용할 수 있다. CPU 코어를 하나만 사용하든 여러 개 사용하든 상관없이 반복문에 의해 바뀌는 변수는 매개변수로 넘겨주어야 한다.