[Go] Channel send/receive 순서 보장

natae·2022년 9월 27일
0

Golang

목록 보기
10/11

개요

  • go의 Channel이 순서를 보장하는지 확인

코드

// go 1.18
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에서 데이터를 꺼낼때, 들어온 순서로 꺼내지 않음

참고문헌

profile
서버 프로그래머

0개의 댓글