채널은 func main와 고루틴 사이에서의 의사소통 창구입니다.
정확히 말하면 내부 쓰레드 간 통신을 위해 Channels가 이용됩니다
고루틴을 통해 무언가 반환한 값을 얻으려면 channel을 이용해야 합니다.
아래 코드가 의도한 바는 isLaunched를 동시적으로 실행하여 결과값을 반환하라는 것입니다.
그러나 아래 코드는 동작하지 않습니다. syntax error가 납니다.
고루틴은 리턴을 하지 않습니다. 채널을 이용합니다.
func main() {
rockets := [2]string{"falcon", "atlas"}
for _, rocket := range rockets {
output := go isLaunched(rocket) // Error!
fmt.Println(output)
}
}
func isLaunched(rocket string) bool {
time.Sleep(time.Second * 5)
return true
}
의도한 동작을 하기 위해서는 아래와 같이 channel을 이용해야 합니다.
[채널 이름] := make(chan [할당할 타입]) 꼴로 생성하며
<-을 이용해 채널에 값을 할당하거나 추출합니다.
func main() {
rockets := [2]string{"falcon", "atlas"}
c := make(chan bool)
for _, rocket := range rockets {
go isLaunched(rocket, c)
}
output := <-c // channel에 전달된 값을 추출. 비동기적이라면 값반환까지 기다림
fmt.Println(output)
}
func isLaunched(rocket string, c chan bool) {
time.Sleep(time.Second * 3) // 비동기적
c <- true // channel에 true 전달
}
다음과 같이 지정된 루틴 이상의 값을 반환하라고 하면 deadlock이 생깁니다.
반대로 지정된 루틴 이하의 채널만 반환하라고 하면 가능은 하지만 반환받지 못하고 사라지는 값이 생길 수도 있습니다.
결론적으론 몇 번 도는 지를 알아야 반환될 채널 갯수를 알 수가 있습니다.
func main() {
rockets := [2]string{"falcon", "atlas"}
c := make(chan bool)
for _, rocket := range rockets {
go isLaunched(rocket, c)
}
fmt.Println(<-c) // 첫번째 완료된 channel 반환
fmt.Println(<-c) // 두번째 완료된 channel 반환
fmt.Println(<-c) // deadlock
}
func isLaunched(rocket string, c chan bool) {
time.Sleep(time.Second * 3) // 비동기적
fmt.Println(rocket)
c <- true // channel에 true 전달
}
bool 뿐만 아니라 다른 타입도 지정하여 channel로 반환할 수 있습니다.
아래에서는 chan string을 이용해보았습니다.
func main() {
rockets := [2]string{"falcon", "atlas"}
c := make(chan string)
for _, rocket := range rockets {
go isLaunched(rocket, c)
}
fmt.Println(<-c) // 첫번째 완료된 channel 반환
fmt.Println(<-c) // 두번째 완료된 channel 반환
}
func isLaunched(rocket string, c chan string) {
time.Sleep(time.Second * 3)
c <- rocket + "is launched"
}
여기서 channel을 출력하는 것은 blocking operation이다. 따라서 js처럼 async/await를 붙여줄 필요는 없다.
fmt.Println(<-c) // blocking operaion. 반환까지 기다림
fmt.Println(<-c) // blocking operaion. 반환까지 기다림
'Programming Language > 🐿️ Go (Golang)' 카테고리의 다른 글
Go 패키지 & Go 모듈 (0) | 2021.05.13 |
---|---|
문자, 문자열 특집 : rune 타입과 string 관련 trick (0) | 2021.05.11 |
Go Routine (1) : concurrency를 위한 고루틴의 원리 및 간단한 활용 + 멀티 코어 (0) | 2020.12.11 |
Go stdlib (2) : sort (0) | 2020.12.08 |
Go stdlib (1) : encoding/json 패키지 (0) | 2020.12.08 |