0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

goroutineでバックグランドタスク実行する例

Posted at

####背景####
以下のことをgoroutineで実現したいです。つまり、メインスレッドでFibonacci計算ではなく、goroutineでバックグランド計算したいです。

スクリーンショット 2021-12-30 14.35.40.png

####例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分、という四つの案があります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?