スレッドの中で チャネルを作れるか 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 // スレッド終了コードの送信
}
スレッドの中で作った構造体と通信を行う方法
これまで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
}
golang エージェントシミュレーション テンプレート サンプルプログラム かたっぱしからセーブ
package main
// C:\Users\ebata\goga\3-12
import (
"fmt"
"sync"
"time"
)
type BUS struct {
number int
}
//var l sync.Mutex
//var c1 chan int
func (bus *BUS) bus_func_recv(lr *sync.Mutex, cr *sync.Cond) {
// 受信(ブロードキャスト専用)
fmt.Println("bus.number by recv:", bus.number)
lr.Lock()
defer lr.Unlock()
fmt.Println("before cr.Wait")
for {
cr.Wait() // ロック
fmt.Println("hi ") // ここで受信処理を行う
}
}
func (bus *BUS) bus_func_send(lb *sync.Mutex, ch1 chan int) {
// 送信専用
fmt.Println("bus.number by send:", bus.number)
lb.Lock()
defer lb.Unlock()
ch1 <- bus.number
}
func main() {
//wg := sync.WaitGroup{}
l := sync.Mutex{}
c1 := make(chan int)
l2 := sync.Mutex{}
c2 := sync.NewCond(&l2)
for i := 0; i < 10; i++ {
bus := BUS{i}
go bus.bus_func_send(&l, c1)
go bus.bus_func_recv(&l2, c2)
}
time.Sleep(time.Second)
c2.Broadcast()
for {
select {
case v := <-c1:
fmt.Println(v)
//default:
// fmt.Println("default")
case <-time.After(3 * time.Second):
return
}
}
close(c1)
//wg.Wait()
//time.Sleep(3 * time.Second)
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
type PERSON struct {
lon_destination float64
lat_destination float64
lon_arrival float64
lat_arrival float64
bus BUS
}
type BUS struct {
lon_present float64
lat_present float64
// person []PERSON
}
func random(min, max float64) float64 {
rand.Seed(time.Now().UnixNano())
return rand.Float64()*(max-min) + min
}
func person(i int, wg *sync.WaitGroup) {
defer wg.Done()
person := PERSON{}
// 出発座標、到着座標の入力
person.lon_destination = random(139.480, 139.460)
person.lat_destination = random(35.602, 35.586)
person.lon_arrival = random(139.480, 139.460)
person.lat_arrival = random(35.602, 35.586)
fmt.Println(person, i)
}
func bus(i int, wg *sync.WaitGroup) {
defer wg.Done()
bus := BUS{}
fmt.Println(bus, i)
}
func main() {
var wg sync.WaitGroup
defer wg.Wait()
// バスエージェントの生成 3台
for i := 0; i < 3; i++ {
wg.Add(1)
go bus(i, &wg)
}
i := 0
for {
time.Sleep(3 * time.Second)
wg.Add(1)
i++
go person(i, &wg)
}
}
package main
// C:\Users\ebata\goga\3-15
import (
"fmt"
"sync"
"time"
)
// BroadCasterは管制システムのイメージに近い だから移動体のオブジェクトには含めない
type BroadCaster struct {
cond *sync.Cond
id int64
msg string
}
func (bc *BroadCaster) Send(msg string) {
bc.cond.L.Lock()
defer bc.cond.L.Unlock()
bc.id++
bc.msg = msg
bc.cond.Broadcast()
}
func (bc *BroadCaster) Recv(last int64) (int64, string) {
bc.cond.L.Lock()
defer bc.cond.L.Unlock()
for bc.id == last {
bc.cond.Wait()
}
return bc.id, bc.msg
}
// broadcaster_busをグローバルで実体化
var (
broadcaster_bus = &BroadCaster{
cond: sync.NewCond(&sync.Mutex{}),
}
)
// broadcaster_personをグローバルで実体化
var (
broadcaster_person = &BroadCaster{
cond: sync.NewCond(&sync.Mutex{}),
}
)
// 単一通信の構造体
type SingleCaster struct {
ch chan int // 単一通信路
lock sync.Mutex // 単一通信路のロック
}
// バス用単一通信の実体化
var (
sc_bus = &SingleCaster{
lock: sync.Mutex{},
ch: make(chan int),
}
)
// 人間用単一通信の実体化
var (
sc_person = &SingleCaster{
lock: sync.Mutex{},
ch: make(chan int),
}
)
// 人間用単一通信の実体化
type CONTROL struct {
number int // 管制番号
}
func (control *CONTROL) control_start() {
// バスへの一斉送信
for i := 0; i < 2; i++ {
time.Sleep(1 * time.Second)
broadcaster_bus.Send(fmt.Sprintf("hello, bus world %d", i))
}
// 人間への一斉送信
for i := 0; i < 2; i++ {
time.Sleep(1 * time.Second)
broadcaster_person.Send(fmt.Sprintf("hello, person world %d", i))
}
for {
select {
// case v := <-c1:
case v_b := <-sc_bus.ch:
fmt.Println("catched from bus send", v_b)
case v_p := <-sc_person.ch:
fmt.Println("catched from person send", v_p)
//default:
// fmt.Println("default")
case <-time.After(3 * time.Second):
return
}
}
}
type BUS struct {
number int // バス車両番号
}
func (bus *BUS) bus_func_recv() {
last := int64(0)
for {
id, msg := broadcaster_bus.Recv(last)
last = id
fmt.Println("broadcaset recv:", bus.number, msg)
}
}
func (bus *BUS) bus_func_send() {
// 送信専用
fmt.Println("bus.number by send:", bus.number)
sc_bus.lock.Lock()
defer sc_bus.lock.Unlock()
sc_bus.ch <- bus.number
}
type PERSON struct {
number int // 人間番号
live bool // 存在フラグ 存在:true 消滅:false
}
func (person *PERSON) person_func_recv() {
last := int64(0)
for {
if person.live {
return
}
id, msg := broadcaster_person.Recv(last)
last = id
fmt.Println("broadcaset recv:", person.number, msg)
}
}
func (person *PERSON) person_func_send() {
// 送信専用
fmt.Println("person.number by send:", person.number)
for {
sc_person.lock.Lock()
sc_person.ch <- person.number
sc_person.lock.Unlock()
time.Sleep(time.Second)
}
}
func main() {
// バス3台
for i := 0; i < 3; i++ {
bus := BUS{i}
go bus.bus_func_send()
go bus.bus_func_recv()
}
// 人間10人
for i := 0; i < 10; i++ {
person := PERSON{i, true}
go person.person_func_send()
go person.person_func_recv()
}
time.Sleep(time.Second)
control := CONTROL{}
go control.control_start()
//close(c1)
//wg.Wait()
time.Sleep(10 * time.Second)
}
package main
// C:\Users\ebata\goga\3-17
import (
"fmt"
"sync"
"time"
)
// BroadCasterは管制システムのイメージに近い だから移動体のオブジェクトには含めない
type BroadCaster struct {
cond *sync.Cond
id int64
msg string
}
func (bc *BroadCaster) Send(msg string) {
bc.cond.L.Lock()
defer bc.cond.L.Unlock()
bc.id++
bc.msg = msg
bc.cond.Broadcast()
}
func (bc *BroadCaster) Recv(last int64) (int64, string) {
bc.cond.L.Lock()
defer bc.cond.L.Unlock()
for bc.id == last {
bc.cond.Wait()
}
return bc.id, bc.msg
}
// broadcaster_busをグローバルで実体化
var (
broadcaster_bus = &BroadCaster{
cond: sync.NewCond(&sync.Mutex{}),
}
)
// broadcaster_personをグローバルで実体化
var (
broadcaster_person = &BroadCaster{
cond: sync.NewCond(&sync.Mutex{}),
}
)
// 単一通信の構造体
type SingleCaster struct {
ch chan int // 単一通信路
lock sync.Mutex // 単一通信路のロック
}
// バス用単一通信の実体化
var (
sc_bus = &SingleCaster{
lock: sync.Mutex{},
ch: make(chan int),
}
)
// 人間用単一通信の実体化
var (
sc_person = &SingleCaster{
lock: sync.Mutex{},
ch: make(chan int),
}
)
// 人間用単一通信の実体化
type CONTROL struct {
number int // 管制番号
}
func control_init(wg *sync.WaitGroup) {
defer wg.Done()
// バスへの一斉送信
for i := 0; i < 2; i++ {
time.Sleep(1 * time.Second)
broadcaster_bus.Send(fmt.Sprintf("hello, bus world %d", i))
}
// 人間への一斉送信
for i := 0; i < 2; i++ {
time.Sleep(1 * time.Second)
broadcaster_person.Send(fmt.Sprintf("hello, person world %d", i))
}
for {
select {
// case v := <-c1:
case v_b := <-sc_bus.ch:
fmt.Println("catched from bus send", v_b)
case v_p := <-sc_person.ch:
fmt.Println("catched from person send", v_p)
//default:
// fmt.Println("default")
case <-time.After(3 * time.Second):
return
}
}
}
type BUS struct {
number int // バス車両番号
person_list []*PERSON // バスに乗っている人
}
func (bus *BUS) bus_func_recv() {
last := int64(0)
for {
id, msg := broadcaster_bus.Recv(last)
last = id
fmt.Println("broadcaset recv:", bus.number, msg)
}
}
func (bus *BUS) bus_func_send() {
// 送信専用
fmt.Println("bus.number by send:", bus.number)
sc_bus.lock.Lock()
defer sc_bus.lock.Unlock()
sc_bus.ch <- bus.number
}
func (bus *BUS) add_person_list(person *PERSON) {
bus.person_list = append(bus.person_list, person)
}
func (bus *BUS) del_person_list(number int) {
for cnt := range bus.person_list {
if number == bus.person_list[cnt].number {
bus.person_list = append(bus.person_list[:number], bus.person_list[number+1:]...)
return
}
}
}
type PERSON struct {
number int // 人間番号
live bool // 存在フラグ 存在:true 消滅:false
}
func (person *PERSON) person_func_recv() {
last := int64(0)
for {
if person.live {
return
}
id, msg := broadcaster_person.Recv(last)
last = id
fmt.Println("broadcaset recv:", person.number, msg)
}
}
func (person *PERSON) person_func_send() {
// 送信専用
fmt.Println("person.number by send:", person.number)
for {
sc_person.lock.Lock()
sc_person.ch <- person.number
sc_person.lock.Unlock()
time.Sleep(time.Second)
}
}
func bus_init(wg *sync.WaitGroup, i int) {
defer wg.Done()
bus := BUS{number: i}
go bus.bus_func_send()
go bus.bus_func_recv()
}
func person_init(wg *sync.WaitGroup, i int) {
defer wg.Done()
person := PERSON{number: i}
go person.person_func_send()
go person.person_func_recv()
}
func main() {
wg := sync.WaitGroup{}
// バス3台
for i := 0; i < 3; i++ {
wg.Add(1)
go bus_init(&wg, i)
}
// 人間10人
for i := 0; i < 10; i++ {
wg.Add(1)
go person_init(&wg, i)
}
time.Sleep(time.Second)
// 管制センタ 1つ
wg.Add(1)
go control_init(&wg)
//close(c1)
//wg.Wait() //本来はこれだが、強制終了の為に
time.Sleep(10 * time.Second)
}
golang 同期処理
うーん、もっとスマートな方法はないかなぁ
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println("Start!")
// boolの型でchannelを作成する
ch1 := make(chan bool)
ch2 := make(chan bool)
ch3 := make(chan bool)
// goroutineを生成して、サブスレッドで処理する
go func() {
time.Sleep(2 * time.Second)
// chに対してtrueを投げる(送信)
ch1 <- true
ch2 <- true
ch3 <- true
}()
go func() {
fmt.Println("func2 start")
<-ch1
fmt.Println("func2 end")
}()
go func() {
fmt.Println("func3 start")
<-ch2
fmt.Println("func3 end")
}()
//isFin := <-ch // <-chだけでもブロック出来る
fmt.Println("before time.Sleep(10 * time.Second)")
time.Sleep(10 * time.Second)
fmt.Println("after time.Sleep(10 * time.Second)")
<-ch3
// chをクローズする
close(ch1)
close(ch2)
close(ch3)
// 受信した値をprintする
//fmt.Println(isFin)
fmt.Println("Finish!")
}
QGISで、国土交通省のPLATEAUの3Dデータの高さ方向が出せない
国土交通省のPLATEAUのサンプルデータを試していますが、3Dデータの高さ方向が出せずにスタックしています。
できるだけ、勉強しないで、てっとり早く成果を出したいだけなんだけどなぁ。
上記の設定にしてみたら、なんかバベルの棟だったか塔だったか、みたいなものが出てきた。
なんか、色々弄っていましたが、
としたら、
のようなものがでてきたけど、多分、これは正解ではないので、また明日以降に挑戦しよう。
あ、ちなみに、QGISのバージョン上げました。
Dial a Ride Problem(DARP)を嫁さんと私の作ったアルゴリズムの両方で解いて貰った件
これが出題
嫁さんの答え
江端のアルゴリズムによる答え
直感的に、私のアルゴリズムが勝っていると思うんだが・・・。
30人を3台のバスで運行するDARPに拡張したバージョン
多分、そこそこ合っていると思うんだけどなー。DARPは正解が分からない(NP困難)問題だからなー。
以上
Golang の arrayとsliceの違い
func totalDistance(sliceA []int, prt int) (dis float64, sliceB []int, max_Bus_Count []int)
という関数を作ったのはいいが、これの呼び出しが上手くできずに、ここ数日作業が滞っていました。
結果としては、正解は以下の通り
var sliceZ [100][]int // または、sliceZ := [100][]int{}
var totalDis [100]float64 // または、totalDis := [100]float64{}
max_Bus_Count := []int{} // または、var max_Bus_Count []inttotalDis[0], sliceZ[0], max_Bus_Count = totalDistance(sliceZ[0], 1)
であり、よく分からんのが、":="と "{}"のペアだが、多分、初期値を放り込めるようにしているものだろう(ここでは入れていないが)。
C言語で書くとこんな感じかと。
#include <stdio.h>
int main() {
int sliceZ[100][90];
double totalDis[100];
int max_Bus_Count[3];int a = totalDistance(sliceZ[0], 1, totalDis[0], max_Bus_Count);
}int totalDistance(int slizeZ, int *p, double totalDis, int max_Bus_Count) {
return 0;
}
こうやってみると、Goの配列宣言は、配列が動的に記載できる分、分かりにくいと思う。
なんで、C言語の宣言を踏襲してくれなかったかなーと思うのだが、
Array
サイズを指定して宣言するもの。実体的な値。メモリを参照するものではない。
a := [3]int64{1, 2, 3}
故に、
a := [3]int{1, 2, 3}
b := a
とすると、aとbが、別のメモリ領域に展開される
Slice
sliceはarrayへの参照を持つデータ構造
s1 := []int{1,2,3} # ここで配列の数(例"3")を宣言しないのがミソ
s2 := s1
s2[1] = 0
こっちは、s1とs2が同じ値になる。
append()で要素数を追加する
江端家ネットワークが繋がらなくなった件 Aterm ATERM-BA73A9
先程、突然、自宅から、全てのWebアクセスができなくなりました。自宅PCの再起動なども試みたのですが、復活しません。
ところが、会社のシステムに繋っているセキュアPC(SPC)に関しては、メールの送信ができました。で、SPCから、kobore.netのIPアドレスを入手して、自宅PCのコマンド画面からpingを打ってみました。
応答あり・・・ということは、DNSが動いていないだけだな、と判断して、取り敢えず、自宅PCのDNSを、強制的に、8.8.8.8 (googleが提供しているDNSサーバ(だったと思う))にしました。
よし。これで、このPCだけは使えるようになりました。
だが、我が家全体のネットワークが使えない状況は続いていますので、とりあえず家族に連絡。
さて、ここでホームルータ(Aterm ATERM-BA73A9 )の設定を見にいってみました。
やはりDNSの表示が出なくなっている。「最新状態に更新」を押しても改善なし。
こういう場面での「再起動」は、事態を悪化させることもあるので、(少なくとも8.8.8.8で動いてはいる)勇気がいるのですが、やってみました。
結果として、DNSが表示されるようになって、自宅ネットワークを再開することができました。
家族に連絡して、完了。
もはや、インターネットなしの生活(仕事、娯楽、その他)は考えられませんので、こういう場面に出会うと、私でも凄く怖いです。
以上
コロナによる死亡率の変動と介護費用のシミュレーション Simulation of corona-induced mortality variation and cost of care
コロナによる死亡率の変動と介護費用のシミュレーション
Simulation of corona-induced mortality variation and cost of care
ダンウロードはここをクリック→第22回生命表_コロナ死亡率シミュレーション