スレッドの中で作った構造体と通信を行う方法
これまでC/C++言語で作ってきたスケーラブルなエージェントシミュレーションを、golangで作りかえようとしています。
これまでもメイン関数に縛られずに、スレッドを自由に動き回すシミュレータは作ってきたのですが、C/C++のスレッドは、いかんせんメモリサイズが大きく、万の単位のエージェントには耐えられないという問題があります。
そんな感じで、golangに乗り換えしているのですが、色々文法が面倒くさいです。
例えば、スレッドの中で作った構造体と通信を行う方法として、go func() で返り値(return)が欲しいと思っていたのだけど、考えてみれば、スレッド化したfunc()は、それが終了するまでreturn値を返す訳ないと気がつきました。
だから,
go func_xxxx()
は、
go i:= finc_xxxx()
もダメだし
i := go func_xxxx()
もダメということで ―― では、スレッドの中の情報にどうやってアクセスすればいいかが、分かりません。
とすれば、スレッド側で送受信機能を持たせることになるのかなぁ、と思って、以下のようなコードを書いてみました。
package main
import (
	"fmt"
	"sync"
)
type BUS struct {
	number int
}
func bus_func(i int, wg *sync.WaitGroup, ch chan int) {
	defer wg.Done()
	bus := BUS{}
	bus.number = i
	pointer_bus := &bus
	fmt.Println(pointer_bus)
	for {
		select {
		case v := <-ch:
			fmt.Println(i, v)
		}
	}
}
func main() {
	var wg sync.WaitGroup
	defer wg.Wait()
	c := make(chan int)
	// バスエージェントの生成 3台
	for i := 0; i < 3; i++ {
		wg.Add(1)
		go bus_func(i, &wg, c)
	}
	// バスエージェントにメッセージを送る
	c <- 50
	c <- 30
	c <- 10
	c <- 50
	c <- 30
	c <- 10
	c <- 50
	c <- 30
	c <- 10
}
ただ、この場合、cチャネルは適当に投げられるので、どのオブジェクトにメッセージに届くか分からないので、もう少し工夫をしてみます。
package main
import (
	"fmt"
	"sync"
)
type BUS struct {
	number int
}
func bus_func(i int, wg *sync.WaitGroup, ch chan int) {
	defer wg.Done()
	bus := BUS{}
	bus.number = i
	pointer_bus := &bus
	fmt.Println(pointer_bus)
	for {
		select {
		case v := <-ch:
			fmt.Println(i, v)
		}
	}
}
//var c = make([]chan int, 3) // 間違い
var c [3]chan int // チャネルをグローバル変数で置く方法の、現時点での正解
// var c []chan int  これは実行時にエラーとなる
func main() {
	var wg sync.WaitGroup
	defer wg.Wait()
	//c := make(chan int)
	// バスエージェントの生成 3台
	for i := 0; i < 3; i++ {
		wg.Add(1)
		c[i] = make(chan int)
		go bus_func(i, &wg, c[i])
	}
	// バスエージェントにメッセージを送る
	c[0] <- 50
	c[1] <- 30
	c[2] <- 10
	c[0] <- 50
	c[1] <- 30
	c[2] <- 10
	c[0] <- 50
	c[1] <- 30
	c[2] <- 10
}