개발이야기/GO
GO - 채널(Channel)
쪼린이
2021. 5. 22. 23:22
이전 글에서 말했듯이 채널은 goroutine을 사용함으로써 main 함수와 goroutine간의 연결을 해주는 파이프 역할을 한다.
이전 글과 동일한 사용 예를 살펴보도록 한다.
func main() {
// 채널 생성 방법
// make(chan 채널에 보낼 정보의 타입)
c := make(chan string)
people := [2]string{"SW", "Chris"}
for _, person := range people {
//goroutine으로 호출
// result := go isNice(person, c)와 같은 형식으로 사용할 수 없다.
go isNice(person, c)
}
}
func isNice(person string, c chan) {
time.Sleep(time.Second)
}
위와 같이 채널을 생성해서 goroutine으로 함수를 호출하면 되는데, 이렇게까지만 하면 저 채널에 어떠한 정보도 들어가지 않는다.
왜냐?! 파이프(채널)에 어떠한 정보도 전달하지 않았기 때문!
채널에 정보를 전달하고 전달 받아 main() 에서 어떠한 코드를 실행하고 싶다면 아래와 같이 하면 된다.
func main() {
// 채널 생성 방법
// make(chan 채널에 보낼 정보의 타입)
c := make(chan string)
people := [2]string{"SW", "Chris"}
for _, person := range people {
//goroutine으로 호출
// result := go isNice(person, c)와 같은 형식으로 사용할 수 없다.
go isNice(person, c)
}
// ✌ chan에서 받아온 정보를 변수에 대입해준다.
resultOne := <-c
resultTwo := <-c
fmt.Println("resultOne:: ", resultOne)
fmt.Println("resultTwo:: ", resultTwo)
}
// chan에서 오고 가는 변수의 타입을 chan 뒤에 표기해준다.
func isNice(person string, c chan string) {
time.Sleep(time.Second)
// 👆 채널 c에 해당 변수를 정보로 넘겨준다.
c <- person + " is nice"
}
결과
이런 결과가 출력되는 순서는 호출을 한 순서와는 무관하다. 이는 전에도 말한 goroutine의 동시성(Concorrency) 때문이다.
출력의 순서를 알아보기 위해서 다음과 같이 출력해보면
func main() {
// 채널 생성 방법
// make(chan 채널에 보낼 정보의 타입)
c := make(chan string)
people := [2]string{"SW", "Chris"}
for _, person := range people {
//goroutine으로 호출
// result := go isNice(person, c)와 같은 형식으로 사용할 수 없다.
go isNice(person, c)
}
// ✌ chan에서 받아온 정보를 변수에 대입해준다.
resultOne := <-c
resultTwo := <-c
fmt.Println("Waiting for messages")
fmt.Println("resultOne:: ", resultOne)
fmt.Println("Got the first msg")
fmt.Println("resultTwo:: ", resultTwo)
fmt.Println("DONE")
}
// chan에서 오고 가는 변수의 타입을 chan 뒤에 표기해준다.
func isNice(person string, c chan string) {
time.Sleep(time.Second)
// 👆 채널 c에 해당 변수를 정보로 넘겨준다.
c <- person + " is nice"
}
출력 결과 :
배열의 가변적 성격을 반영하여 코드를 아래와 같이 for문으로도 바꿀 수 있다.
func main() {
// 채널 생성 방법
// make(chan 채널에 보낼 정보의 타입)
c := make(chan string)
people := [2]string{"SW", "Chris"}
for _, person := range people {
//goroutine으로 호출
// result := go isNice(person, c)와 같은 형식으로 사용할 수 없다.
go isNice(person, c)
}
for i := 0; i < len(people); i++ {
//fmt.Println("Waiting for ", i)
fmt.Println(<-c)
}
}
// chan에서 오고 가는 변수의 타입을 chan 뒤에 표기해준다.
func isNice(person string, c chan string) {
time.Sleep(time.Second)
// 👆 채널 c에 해당 변수를 정보로 넘겨준다.
c <- person + " is nice"
}