Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- C
- GO 언어
- windows
- bitcoin
- JavaScript
- FOR
- range
- Sync
- install
- write
- 리뷰
- window
- tcp
- Python
- json
- mutex
- Callback
- go언어
- http
- Close
- go
- 영화
- 책
- channel
- package
- c++
- File
- Linux
- Golang
- API
Archives
- Today
- Total
Code Habit
Go ) 클로저와 고루틴 본문
함수 안에서 클로저를 정의한 뒤 고루틴으로 실행할 수 있다.
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 코어를 하나만 사용하든 여러 개 사용하든 상관없이 반복문에 의해 바뀌는 변수는 매개변수로 넘겨주어야 한다.