スレッドの中で チャネルを作れるか golang goroutine

package main

import (
"fmt"
"time"
)

var ch chan int // チャネルを運ぶためのグローバルチャネル

func bus_func(i int) {
ch = make(chan int) // スレッドの中でチャネルを作っても動かない

ch <- 10
fmt.Println("After", ch)

time.Sleep(3)
}

func main() {

go bus_func(1)

fmt.Println(<-ch)

}

スレッドの中で(というかサブルーチンの中で)チャネルは厳しいのかな?

package main

import (
	"fmt"
	"time"
)

var ch chan int // チャネルを運ぶためのグローバルチャネル

func bus_func(i int) {

	ch <- 10
	fmt.Println("After", ch)

	time.Sleep(3)
}

func main() {

	ch = make(chan int) // メインで作った場合は動く

	go bus_func(1)

	fmt.Println(<-ch)

}

チャネルを定数で確保しない方法ってないかなぁ。

スレッドで、オブジェクトを実体化して、そこで送受信させる。

package main

import (
	"fmt"
	"sync"
	"time"
)

type BUS struct {
	number int
}

func bus_func(i int, wg *sync.WaitGroup, ch1 chan int, ch2 chan int) {
	defer wg.Done()

	t := time.NewTicker(1 * time.Second) // 1秒おきに通知

	bus := BUS{}
	bus.number = i

	pointer_bus := &bus

	fmt.Println(pointer_bus)

	// 待受
	for {
		select {
		case v := <-ch1: // 受信
			if v == -1 { //終了コードの受信
				return // スレッドを自滅させる
			} else {
				fmt.Println(v)
			}
		case <-t.C: // 送信 (1秒まったら、むりやりこっちにくる)
			ch2 <- i + 100
		}
	}

}

//var c = make([]chan int, 3) // 間違い
// var c []chan int  これは実行時にエラーとなる

var c1 [3]chan int // チャネルをグローバル変数で置く方法の、現時点での正解
var c2 [3]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)

		c1[i] = make(chan int)
		c2[i] = make(chan int)
		go bus_func(i, &wg, c1[i], c2[i])
	}

	// バスエージェントにメッセージを送る

	c1[0] <- 50
	c1[1] <- 30
	c1[2] <- 10

	c1[0] <- 50
	c1[1] <- 30
	c1[2] <- 10

	c1[0] <- 50
	c1[1] <- 30
	c1[2] <- 10

	fmt.Println(<-c2[0])
	fmt.Println(<-c2[1])
	fmt.Println(<-c2[2])

	c1[0] <- -1 // スレッド終了コードの送信
	c1[1] <- -1 // スレッド終了コードの送信
	c1[2] <- -1 // スレッド終了コードの送信

}

2021/11,江端さんの技術メモ

Posted by ebata