無限ループのgoroutineも止めることができるcontext.Context

2022年10月9日

私の作るエージェントプログラムは、エージェントが数千~数万回のレベルで発生ー消滅をするものなので、エジェントの消滅時に、確実に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)
	}

}

 

 

 

 

2022年10月9日2021/12,江端さんの技術メモ

Posted by ebata