개요
- go의 Channel이 순서를 보장하는지 확인
코드
package main
package study
import (
"fmt"
"sync"
)
var channel1 chan int
var channel2 chan int
var quitChan chan struct{}
func main() {
TestChannelOrder(0)
fmt.Println("------------------")
TestChannelOrder(10)
}
func TestChannelOrder(chanSize int) {
channel1 = make(chan int, chanSize)
channel2 = make(chan int, chanSize)
quitChan = make(chan struct{})
go loop_goroutine()
wg := sync.WaitGroup{}
for i := 0; i < 10; i++ {
go func(index int) {
wg.Add(1)
channel1 <- index
fmt.Printf("In %d\n", index)
val := <-channel2
fmt.Printf("Out %d\n", val)
wg.Done()
}(i)
}
wg.Wait()
close(quitChan)
close(channel1)
close(channel2)
}
func loop_goroutine() {
for {
select {
case val := <-channel1:
channel2 <- val
case <-quitChan:
return
}
}
}
출력
In 1
Out 1
In 0
Out 0
In 5
Out 5
In 2
Out 2
In 3
Out 3
In 4
Out 4
In 9
Out 9
In 8
Out 8
In 7
Out 7
In 6
Out 6
------------------
In 2
Out 2
In 0
In 9
Out 0
In 3
In 4
Out 1
In 1
Out 6
In 8
Out 3
In 6
Out 5
In 5
Out 7
Out 4
Out 9
In 7
Out 8
결론
- size = 0인 경우, 큐 처럼 순서가 보장 (Unbuffered)
- send 후 receive할 때 까지 send가 블락되기 때문
- size > 0인 경우, 순서가 보장되지 않음 (Buffered)
- receive와 상관없이 size만큼 send를 미리 할 수 있음
- 이후 Channel에서 데이터를 꺼낼때, 들어온 순서로 꺼내지 않음
참고문헌