####背景####
以下のことをgoroutineで実現したいです。つまり、メインスレッドでFibonacci計算ではなく、goroutineでバックグランド計算したいです。
####例1####
func main() {
endChannel := make(chan int)
go backgroundTask(endChannel)
<- endChannel // main goroutineを終了させるまで、endChannelの補填を待ち
}
func backgroundTask(endChannel chan int) {
fmt.Println("background running...")
fmt.Println("result: ",calculate(45))
endChannel <- 1
}
func calculate(n int) int{
if n < 2 {
return n
}
return calculate(n - 1) + calculate(n - 2)
}
####例2####
func main() {
endChannel := make(chan int)
go backgroundTask(endChannel)
for _ = range endChannel {
}
}
func backgroundTask(endChannel chan int) {
fmt.Println("background running...")
fmt.Println("result: ",calculate(45))
endChannel <- 1
close(endChannel)
}
func calculate(n int) int{
if n < 2 {
return n
}
return calculate(n - 1) + calculate(n - 2)
}
####例3####
func main() {
endChannel := make(chan int)
go backgroundTask(endChannel)
for {
_,ok := <- endChannel
if !ok {
break
}
}
}
func backgroundTask(endChannel chan int) {
fmt.Println("background running...")
fmt.Println("result: ",calculate(45))
endChannel <- 1
close(endChannel)
}
func calculate(n int) int{
if n < 2 {
return n
}
return calculate(n - 1) + calculate(n - 2)
}
####例4####
func main() {
endChannel := make(chan int)
go backgroundTask(endChannel)
for {
select {
case <- endChannel:
return
}
}
}
func backgroundTask(endChannel chan int) {
fmt.Println("background running...")
fmt.Println("result: ",calculate(45))
endChannel <- 1
//close(endChannel) // case<-endChannelの処理はfor分を終了してあるから、closeしなくても良いです。
}
func calculate(n int) int{
if n < 2 {
return n
}
return calculate(n - 1) + calculate(n - 2)
}
####例5####
func main() {
wg := sync.WaitGroup{}
wg.Add(1)
go backgroundTask(&wg)
wg.Wait()
}
func backgroundTask(wg *sync.WaitGroup) {
fmt.Println("background running...")
fmt.Println("result: ",calculate(45))
wg.Done()
}
func calculate(n int) int{
if n < 2 {
return n
}
return calculate(n - 1) + calculate(n - 2)
}
###まとめ###
バックグランドで動いているgoroutineをメインgoroutineから待つ必要があるため、専用なendChannelを用意するか、sync.WaitGroupでコントロールするかという二つの案があります。
さらに、endChannelをメインgoroutineから待つ方法はfor文、for range文、<- endChannel、for select分、という四つの案があります。