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 |
Tags
- GO 언어
- http
- channel
- JavaScript
- File
- write
- windows
- Golang
- Close
- go
- go언어
- 책
- API
- FOR
- bitcoin
- c++
- C
- tcp
- mutex
- install
- 영화
- Python
- Callback
- window
- Sync
- 리뷰
- package
- range
- json
- Linux
Archives
- Today
- Total
Code Habit
Go ) Select 본문
Go 언어는 여러 채널을 손쉽게 사용할 수 있도록 select 분기문을 제공한다.
- select { case <- 채널 : 코드 }
1
2
3
4
5
6
7
8
|
select {
case <- 채널1:
// 채널1에 값이 들어왔을 때 실행할 코드를 작성한다.
case <- 채널2:
// 채널2에 값이 들어왔을 때 실행할 코드를 작성한다.
default:
// 모든 case의 채널에 값이 들어오지 않았을 때 실행할 코드를 작성합니다.
}
|
select 분기문은 switch 분기문과 비슷하지만 select 키워드 뒤에 검사할 변수를 따로 지정하지 않으며 각 채널에 값이 들어오면 해당 case가 실행된다. ( close 함수로 채널을 닫았을 때도 case가 실행된다. ) 그리고 보통 select를 계속 처리할 수 있도록 for로 반복해준다. (반복하지 않으면 한 번만 실행하고 끝낸다.)
default에 적절한 처리를 하지 않으면 CPU 코어를 모두 점유하므로 주의하자 !!
다음은 select 분기문을 활용한 예제이다.
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
32
33
34
35
36
37
38
|
package main
import (
"fmt"
"time"
)
func main() {
c1 := make(chan int) // int형 채널 생성
c2 := make(chan string) // string형 채널 생성
go func() {
for {
c1 <- 10 // 채널 c1에 10을 보낸 뒤
time.Sleep(100 * time.Millisecond) // 100 밀리초 대기
}
}()
go func() {
for {
c2 <- "Hello, world!" // 채널 c2에 Hello, world!를 보낸 뒤
time.Sleep(500 * time.Millisecond) // 500 밀리초 대기
}
}()
go func() {
for {
select {
case i := <- c1: // 채널 c1에 값이 들어왔다면 값을 꺼내서 i에 대입
fmt.Println("c1 :", i)
case s := <- c2: // 채널 c2에 값이 들어왔다면 값을 꺼내서 s에 대입
fmt.Println("c2 :", s)
}
}
}()
time.Sleep(10 * time.Second) // 10초 동안 프로그램 실행
}
|
case에서는 case i := <- c1: 처럼 채널에서 값을 꺼낸 뒤 변수에 바로 저장할 수 있다. 만약 꺼낸 값을 사용하지 않는다면 case <- c1: 처럼 변수를 생략해도 된다.
실행 결과
c1 : 10
c2 : Hello, world!
c1 : 10
c1 : 10
c1 : 10
c1 : 10
c2 : Hello, world!
c1 : 10
c1 : 10
c1 : 10
...
|
select 분기문은 채널에 값을 보낼 수도 있다.
- case 채널 <- 값: 코드
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
32
33
34
35
36
37
38
|
package main
import (
"fmt"
"time"
)
func main() {
c1 := make(chan int) // int형 채널 생성
c2 := make(chan string) // string형 채널 생성
go func() {
for { // 무한 루프
i := <- c1 // 채널 c1에서 값을 꺼낸 뒤 i에 대입
fmt.Println("c1 :", i) // i 값을 출력
time.Sleep(100 * time.Millisecond) // 100 밀리초 대기
}
}()
go func() {
for { // 무한루프
c2 <- "Hello, world!" // 채널 c2에 Hello, world!를 보낸 뒤
time.Sleep(500 * time.Millisecond) // 500 밀리초 대기
}
}()
go func() {
for { // 무한루프
select {
case c1 <- 10: // 매번 채널 c1에 10을 보냄
case s := <- c2: // 채널 c2에 값이 들어왔다면 값을 꺼내서 s에 대입
fmt.Println("c2 :", s)
}
}
}()
time.Sleep(10 * time.Second) // 10초 동안 프로그램 실행
}
|
실행 결과
c2 : Hello, world!
c1 : 10
c1 : 10
c1 : 10
c1 : 10
c1 : 10
c2 : Hello, world!
c1 : 10
c1 : 10
...
|
예제에서는 c1, c2 두개의 채널을 사용했지만 채널 c1 한개로 select에서 값을 보내거나 받을 수도 있다.