無限ループのgoroutineも止めることができるcontext.Context
私の作るエージェントプログラムは、エージェントが数千~数万回のレベルで発生ー消滅をするものなので、エジェントの消滅時に、確実にgoroutineを消滅させる必要があります。
しかし無限ループでイベント待ちをしているgoroutineを止める方法で、苦慮してきたのですが、問答無用でgoroutineを潰す、context.Contextというものを見つけて ―― 『これまでの苦労は一体なんだったんだ』と思っています。
まあ、こういうことって、結構ありますけどね。
package main
import (
	"context"
	"fmt"
	"time"
)
func main() {
	ctx, cancel := context.WithCancel(context.Background())
	go loop(ctx)
	// 2.5秒待つ
	time.Sleep(2500 * time.Millisecond)
	// ここで loop() を止める
	cancel()
	// 2回呼び出しても大丈夫
	cancel()
	println("finish")
}
// 無限ループする関数
func loop(ctx context.Context) {
	for {
		fmt.Println("test")
		time.Sleep(time.Second)
	}
}
親から子どもを一斉に消滅させる方法については、明日、片付けます。
なお、こっちの defer cancel()を使う方がスマートです。
package main
import (
	"context"
	"fmt"
	"time"
)
func main() {
	ctx, cancel := context.WithCancel(context.Background())
	go loop(ctx)
	defer cancel()
	// 2.5秒待つ
	time.Sleep(2500 * time.Millisecond)
	println("finish")
}
// 無限ループする関数
func loop(ctx context.Context) {
	for {
		fmt.Println("test")
		time.Sleep(time.Second)
	}
}