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

=======================

https://github.com/SierraSoftworks/multicast

マルチキャストでは、チャンネルをリスナーのリンクリストとして実装しています。リスナーは、受信したメッセージを次のリスナーに自動的に転送してから、自分のCチャンネルで公開します。

このアプローチにより、チャネルに属するリスナーの配列を維持する必要がなくなり、実装が大幅に簡素化されます。

=======================

以下は、readme.mdに記載されているプログラムを、ちょっとだけ改造したもの(syncを加えた)

package main

import (
	"fmt"
	"sync"

	"github.com/SierraSoftworks/multicast"
)

func main() {
	c := multicast.New()
	wg := sync.WaitGroup{}

	wg.Add(2)

	go func() {
		l := c.Listen()
		wg.Done()
		defer wg.Done()
		for msg := range l.C {
			fmt.Printf("Listener 1: %s\n", msg)
		}
		fmt.Println("Listener 1 Closed")
	}()

	go func() {
		l := c.Listen()
		wg.Done()
		defer wg.Done()
		for msg := range l.C {
			fmt.Printf("Listener 2: %s\n", msg)
		}
		fmt.Println("Listener 2 Closed")
	}()

	wg.Wait()
	wg.Add(2)

	c.C <- "1 Hello World!"
	c.C <- "2 Hello World!"
	c.C <- "3 Hello World!"
	c.C <- "4 Hello World!"

	c.Close()

	wg.Wait()
}

 

ebata@DESKTOP-P6KREM0 MINGW64 ~/goga/3-7
$ go run main.go
Listener 1: 1 Hello World!
Listener 1: 2 Hello World!
Listener 2: 1 Hello World!
Listener 2: 2 Hello World!
Listener 2: 3 Hello World!
Listener 2: 4 Hello World!
Listener 2 Closed
Listener 1: 3 Hello World!
Listener 1: 4 Hello World!
Listener 1 Closed

久しぶりに、「世界に感謝を」という気持ちになりました。

https://github.com/SierraSoftworks/multicast/blob/main/channel.goの、コメントに日本語コメント(翻訳)を付けたもの

package multicast

import "sync"

// Channel represents a multicast channel container which provides
// a writable channel C and allows multiple listeners to be connected.
// Channelは、書き込み可能なチャンネルCを提供し、複数のリスナーの接続を可能にする
// マルチキャストチャンネルコンテナを表します。

type Channel struct {
	// C is a writable channel on which you can send messages which will
	// be delivered to all connected listeners.
	// Cは書き込み可能なチャンネルで、接続されているすべてのリスナーに配信される
        // メッセージを送ることができます。

	C chan<- interface{}

	c chan interface{}
	l *Listener
	m sync.Mutex
}

// New creates a new multicast channel container which can have listeners
// connected to it and messages sent via its C channel property.
// このコンテナにはリスナーが接続され、C channelプロパティでメッセージが送信されます。

func New() *Channel {
	c := make(chan interface{})

	return From(c)
}

// From creates a new multicast channel which exposes messages it receives
// on the provided channel to all connected listeners.
// Fromは、新しいマルチキャストチャネルを作成し、提供されたチャネルで受信した
// メッセージを、接続されているすべてのリスナーに公開します。

func From(c chan interface{}) *Channel {
	return &Channel{
		C: c,
		c: c,
	}
}

// Listen returns a new listener instance attached to this channel.
// Each listener will receive a single instance of each message sent
// to the channel.
// Listenは、このチャンネルに接続された新しいリスナーのインスタンスを返します。
//各リスナーは、チャンネルに送信された各メッセージのインスタンスを1つずつ受信します。

func (c *Channel) Listen() *Listener {
	c.m.Lock()
	defer c.m.Unlock()

	if c.l == nil {
		c.l = NewListener(c.c)
	} else {
		c.l = c.l.Chain()
	}

	return c.l
}

// Close is a convenience function for closing the top level channel.
// You may also close the channel directly by using `close(c.C)`.
// Closeは、トップレベルのチャンネルを閉じるための便利な関数です。
// close(c.C)`を使ってチャンネルを直接閉じることもできます。

func (c *Channel) Close() {
	c.m.Lock()
	defer c.m.Unlock()

	close(c.c)
}

 

https://github.com/SierraSoftworks/multicast/blob/main/listener.goの、コメントに日本語コメント(翻訳)を付けたもの

package multicast

// Listener represents a listener which will receive messages
// from a channel.
// リスナーは、チャンネルからのメッセージを受信するリスナーを表します。
type Listener struct {
	C <-chan interface{}
	f chan interface{}
}

// NewListener creates a new listener which will forward messages
// it receives on its f channel before exposing them on its C
// channel.
// NewListenerは、Cチャンネルで公開する前に、fチャンネルで受信したメッセージを
// 転送する新しいリスナーを作成します。

// You will very rarely need to use this method directly in your
// applications, prefer using From instead.
// アプリケーションでこのメソッドを直接使用することはほとんどないと思いますが、
// 代わりにFromを使用してください。

func NewListener(source <-chan interface{}) *Listener {
	out := make(chan interface{}, 0)
	l := &Listener{
		C: out,
	}

	go func() {
		for v := range source {
			if l.f != nil {
				l.f <- v
			}
			out <- v
		}

		if l.f != nil {
			close(l.f)
		}
		close(out)
	}()

	return l
}

// Chain is a shortcut which updates an existing listener to forward
// to a new listener and then returns the new listener.
// Chainは、既存のリスナーを更新して新しいリスナーに転送し、
// その新しいリスナーを返すショートカットです。

// You will generally not need to make use of this method in your
// applications.
// 一般的には、このメソッドを使用する必要はありません。

func (l *Listener) Chain() *Listener {
	f := make(chan interface{})
	l.f = f
	return NewListener(f)
}

 

package main

import (
	"fmt"
	"sync"
	"time"

	"github.com/SierraSoftworks/multicast"
)

func bus_func(i int, wg *sync.WaitGroup, ch *multicast.Channel) {

	l := ch.Listen()
	wg.Done()
	defer wg.Done()

	/*
		// これだといいんだけど、多面待ちができない
		for msg := range l.C {
			fmt.Printf("Listener %d: %s\n", i, msg)
		}

	*/

	for {
		select {
		case v := <-l.C:
			if v == nil {
				return
			}
			fmt.Println(i, v)
		}
		//time.Sleep(1 * time.Second)
	}

	//fmt.Printf("Listener %d Closed\n", i)
}

func main() {
	c := multicast.New()
	wg := sync.WaitGroup{}

	/*
		wg.Add(2)
		go func() {
			l := c.Listen()
			wg.Done()
			defer wg.Done()
			for msg := range l.C {
				fmt.Printf("Listener 1: %s\n", msg)
			}
			fmt.Println("Listener 1 Closed")
		}()

		go func() {
			l := c.Listen()
			wg.Done()
			defer wg.Done()
			for msg := range l.C {
				fmt.Printf("Listener 2: %s\n", msg)
			}
			fmt.Println("Listener 2 Closed")
		}()
	*/

	for i := 0; i < 3; i++ {
		wg.Add(1)
		go bus_func(i, &wg, c)
	}

	wg.Wait()
	wg.Add(2)

	c.C <- "1 Hello World!"
	time.Sleep(time.Second)

	c.C <- "2 Hello World!"
	time.Sleep(time.Second)

	c.C <- "3 Hello World!"
	time.Sleep(time.Second)
	c.C <- "4 Hello World!"

	c.Close()

	wg.Wait()
}

 

package main

import (
	"fmt"
	"sync"
	"time"

	"github.com/SierraSoftworks/multicast"
)

func bus_func(i int, wg *sync.WaitGroup, ch *multicast.Channel) {

	l := ch.Listen()
	wg.Done()
	defer wg.Done()

	/*
		// これだといいんだけど、多面待ちができない
		for msg := range l.C {
			fmt.Printf("Listener %d: %s\n", i, msg)
		}

	*/

	tick := time.Tick(time.Millisecond * 10000)

	for {
		select {
		case v := <-l.C:
			if v == nil { // c.Close() で goroutineをクローズする
				return
			}
			fmt.Println(i, v)

		case t := <-tick:
			// ここに送信するものを入れる
			fmt.Println("tiched", t)
		}

		//time.Sleep(1 * time.Second)
	}

	//fmt.Printf("Listener %d Closed\n", i)
}


func main() {
	c := multicast.New()
	wg := sync.WaitGroup{}

	/*
		wg.Add(2)
		go func() {
			l := c.Listen()
			wg.Done()
			defer wg.Done()
			for msg := range l.C {
				fmt.Printf("Listener 1: %s\n", msg)
			}
			fmt.Println("Listener 1 Closed")
		}()

		go func() {
			l := c.Listen()
			wg.Done()
			defer wg.Done()
			for msg := range l.C {
				fmt.Printf("Listener 2: %s\n", msg)
			}
			fmt.Println("Listener 2 Closed")
		}()
	*/

	for i := 0; i < 5; i++ { // ここの"5"は  (Aに飛ぶ)
		wg.Add(1)
		go bus_func(i, &wg, c)
	}

	wg.Wait()

	wg.Add(5) // (Aから)ここの"5"と一致している必要がある(が理由が分からん)

	c.C <- "11111!"
	//time.Sleep(time.Second)

	c.C <- "22222!"
	//time.Sleep(time.Second)

	c.C <- "33333!"
	//time.Sleep(time.Second)

	c.C <- "44444!"
	//time.Sleep(3 * time.Second)

	c.Close() // これでスレッドを全部止める

	wg.Wait()
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2021/11,江端さんの忘備録

コロナ禍の在宅勤務で、働き手が、終日自宅にいることが多くなりました。

With telecommuting during the Corona disaster, workers are now often at home all day.

嫁さんによると、『家の中で、旦那が一日中ジャージを着ていることに我慢ができない』という奥さんが多いのだそうです。

According to my wife, many wives say, 'I can't stand the fact that my husband wears their jersey all day long in the house'.

江端:「ジャージは、機能性に高い優れた衣服であると思うが?」

Ebata: "I think jerseys are excellent, highly functional garments"

嫁さん:「じゃあ、一日中、ジャージを着れと言われたら、抵抗はない?」

Wife: "So, if I asked you to wear a jersey all day, would you resist?"

私は即答しました。

I gave her an immediate answer.

江端:「1mmもないな。むしろ歓迎といってもいいだろう。それを嫌悪する心理が分からない」

Ebata: "Not even a millimeter. It's more like a welcome. I don't understand the psychology behind your dislike of it."

嫁さん:「じゃあ、私が終日ブルマを履いて、家事をしていてもいいの?」

Wife: "Then Can I wear my bloomer all day during housework"

江端:「それは絶対に嫌だ。勘弁して欲しい。しかし、ジャージとブルマは、等価交換できる概念か?」

Ebata: "I absolutely hate that. I want you to give me a break. But are jerseys and bloomers concepts that can be exchanged equivalently?"

嫁さん:「両方とも、日常的な着衣ではないと意味では同じだと思う」

Wife: "I think they're both the same in the sense that they're not everyday garments."

嫁さんは、「等価交換」と言うのであれば、ジャージとブルマを、部屋着として着衣する夫婦は「相互に認容するか」「相互の拒否するか」のどちらかしかない、と、言っているのです。

My wife said that if we are talking about "equivalent exchange," then a couple who wears jerseys and bloomers as loungewear can only have "mutual acceptance" or "mutual rejection.

江端:「いや、『ブルマの日常的着衣』と『ジャージの日常的着衣』は、その非日常感において、比較にならないほどの差があると思うが」

Ebata: "No, I think there's an incomparable difference in the sense of the extraordinary between 'the daily wear of bloomers' and 'the daily wear of jerseys.

嫁さん:「私には、『同程度に忌避される非日常』だと思う」

Wife: "For me, it's 'equally repellent extraordinary'"

-----

この議論が、ロジックでは解決できないことは、嫁さんも私も分かっています。

Both My wife and I know that this discussion cannot be solved by logic.

これは感性の問題だからです。

This is because it is a matter of sensitivity.

ただ、感性の違いであっても、その違いを相対的に認識することはできます。

However, even differences in sensitivity can be recognized relative to each other.

私は「ブルマは圧倒的に非日常」であると感じているのに対して、嫁さんは「ブルマもジャージも同程度に非日常、かつ、忌避的」である、と感じている訳です。

I feel that bloomers are overwhelmingly unusual, while my wife feels that bloomers and jerseys are equally unusual and repellent.

『日常と非日常を決定する主体は、自分ではなく他人である』

"The subject who determines the ordinary and the extraordinary is not myself, but others"

その一点において、私たち夫婦は合意ができていますので、お互いの受忍範囲を越えるような着衣や装飾はしないことにしています。

On that one point, we come to an agreement, so we do not wear clothes or decorations that are beyond our mutual acceptance.

というか、私は、嫁さんの着衣(『ブルマの日常的着衣」というような超非日常的事項を除けば)には興味がありません。

I mean, I'm not interested in my wife's clothes (except for very unusual matters such as "daily wearing of bloomers").

結果として、嫁さんが、私の着衣に、一方的にクレーム(要求)をしてくるだけです。

As a result, my wife just makes a one-sided complaint (demand) about my clothes.

-----

嫁さん:「私は、"ステテコ"も、だめだな」

Wife:"I cannot stand 'long men's underpants'"

江端:「うちのじいちゃん(父)は、ステテコを部屋着として着衣していたぞ」

Ebata: "My grandpa (father) used to wear 'long men's underpants' as his loungewear.

嫁さん:「おじいちゃんはいいんだよ」

Wife: "Grandpa is O.K."

江端:「おい! 『非日常』に、対象別の基準が入ってきているぞ」

Ebata: "Hey! There's a subject-specific standard coming in for "unusual."

嫁さん:「だから、『非日常』は、言語化できないんだってば」

Wife: "That's why 'extraordinary' can't be verbalized."

江端:「それは、分かってはいるけど、言語化を試みて、なんとか1mmでも歩みよれる努力はしよう」

Ebata: "I know that, but we're going to try to verbalize it and make an effort to get closer, even if it's only by 1mm.

2021/11,江端さんの忘備録

(昨日の続きです)

(Continuation from yesterday)

■国民のマイナンバーカードの取得率が低いのは、政府がメリットを提示できていないからです。

マイナンバーカードと運転免許証と保険証の統合をする程度のことに、何年かかっとるんだ? と思いますし、そこに、クレジットカードとSUICAも、機能アドインするくらいのことができんのかなぁ、と思っています。

The reason why people are not getting their own My Number cards is because the government has not been able to present the benefits. How many years is it going to take to integrate my number card with my driver's license and insurance card? I also wonder if it would be possible to add credit card and SUICA functions to the cards.

■私は、コロナ禍においてもリモートワークが進まなかった会社は、基本的に、社長一人が(×罰社員)がIT音痴である、ということを知っています。

社長は「できない」のではなく「やらない」ということも知っています。

社長が仕事のやり方を替えないのは「面倒くさい」からです。

I know that in companies where remote work was not promoted even during the Corona disaster, the president alone (not the employees) is basically IT illiterate. I know that it's not that the president "can't" do it, but that he "won't" do it. The reason why the president doesn't change the way he works is because it's too much trouble.

■IT統合が死ぬほど難しいことを、私は良く知っています。

ですから、私がシステムを作る時には、基本的にはスクラッチから作り直すことにします。

しかし、これは、私のシステムが、実験目的であり、組織的構造や社内政治圧力と無関係で作れる、という気楽さがあるからであることも分かっています。

I know very well that IT integration is deathly difficult, so when I build a system, I basically rebuild it from scratch. However I also know that this is because my systems are experimental, and I am comfortable building them independently of organizational structure and internal political pressure.

■それでも、銀行システムが2021年だけで6回停止するというのは、『異常事態』である、ということは分かります。

電子政府とか、官民連携とかを、本気で実現したいのであれば、システム開発部隊の長に、社長、あるいは、内閣総理大臣ですら口を出せない程度と、協力な権限を与えなければ不可能であることは、私には「手に取るように分かる」のです。

The fact that the banking system will be shut down six times in 2021 alone is an extraordinary situation. If you really want to realize e-government or public-private partnership, you have to give the head of the system development unit a degree of authority and cooperation that even the president or the prime minister cannot interfere with.

■権力のあるITオンチが、システム開発の最大のガン、であることは、私にだって分かります。

だって、どうせ、やつら『何だか分からんが、とにかく動かせ!止めるな! 予算を越えるな!!』って叫んでいるだけでしょう?

なんでそんなこと分かるかって?

そりゃ、あの政治家たちのITオンチぶりを見ていれば、分かりますよ。

I know that IT illiterates with power are the biggest cancer in system development. Because, anyway, they're like, "I don't know what it is, but just move it! Don't stop! Don't exceed the budget!" How do I know that? Well, you only have to look at how IT-illiterate those politicians are.

以上

That's all.

2021/11,江端さんの忘備録

11月号のコラムの原稿(月末リリースの予定)を見直ししていて、『冗長だな』と思い、やむなく削除したフレーズを、ここに、残しておきます。

I was reviewing the draft of my column for the November issue (to be released at the end of the month), and I thought it was redundant, so I had to delete some phrases.

■国内でTOEIC信仰に狂っているだけで、海外に出ていこうとれず、海外の人材を使いこなる器量もない私たちヘタレ日本人のことは、こちら(*)に山ほど書きました。

I've written a lot about those of us Japanese who are just crazy about the TOEIC in Japan, but don't want to go abroad and don't have the ability to use foreign talent

■今回の調査で、ようやく日本で始まった子どものIT教育が、イギリスや米国に20年近くビハインドであることを知って、ショックを受けましたし、日本のITのR&Dの予算のショボさに愕然としたりしました(*)

In this survey, I was shocked to learn that children's IT education, which has finally started in Japan, is almost 20 years behind that of the UK and the US, and I was also shocked at the small budget for IT R&D in Japan (*).

■日本人のノーベル受賞者って、ほとんど日本の大学に在籍していないんだけど、これで『日本の誇り』なんて言えるのかな、と思っています。

Most of the Japanese Nobel laureates have not been enrolled in Japanese universities, and I wonder how they can be called "proud of Japan".

■私の同僚で起業した奴は何人かいたけど(全員、不快な奴だったけど、確かに優秀ではあった)、その後、名前を聞いたことがないんだが、ちゃんと我が国は彼らを支援していたのだろうか、と今でも疑問です。

There were a few of my colleagues who started their own businesses (they were all unpleasant, but certainly brilliant), but I haven't heard their names since, and I still wonder if our country was supporting them properly.

■日本の企業でGAFAのようになれる可能性があったのは、NTTドコモの"i-mode"くらいだったような気がするんだけどなぁ、と思い返しています。

I think the only Japanese company that had the potential to be like GAFA was NTT Docomo's "i-mode".

■若い研究員の考える新しいネットサービスが、『市場規模と費用対効果の試算を出せ』という幹部の一言によって潰され、彼らが、エクセルの計算に疲れ張てて、士気を失なっていくのを、私は何度も見ました。

Many times I have seen young researchers' ideas for new Internet services crushed by a single word from a senior executive: "Give me an estimate of the market size and cost-effectiveness," and I have seen them become demoralized, exhausted by Excel calculations.

(続く)

2021/11,江端さんの忘備録

今週末は、原稿締切前の修羅場週なので、私の机の上の写真で勘弁して下さい。

This weekend is the week before my manuscript deadline, so please excuse the disclosure of the photo on my desk.

2021/11,江端さんの忘備録

『アンガーコントロール』というのは、私には難しい ―― という話は、これまでに何度もしてきました。

I've often said that "anger control" is difficult for me.

『怒りが発生したら、6秒待て』と良く書かれていますが、私の怒りは、その程度のライフタイムではありません。

It is often said, "When anger arises, wait six seconds," but my anger does not have that kind of lifetime.

私の場合、6日、60日は、怒りが軽く維持しますし、へたすると6年間以上、維持し続けることがあります。

In my case, my anger stays light for six or sixty days, and sometimes for six years or more.

私は、一瞬で「カーッ」となるような怒りは少ないです。

I have very little anger that can boil over in an instant.

ネチっこくて、ダラダラと長く、かつ、自分のロジックで、怒りを連鎖反応させて、臨界に達するような、たちの悪い怒り方をします。

In my case, I have a nasty anger that is persistent, lingering and long, and using my own logic, I can set off a chain reaction of anger that reaches critical mass.

まあ、はっきり言って、『私って、かなり最低』という自覚はあります。

Well, to put it bluntly, I'm aware that 'I'm pretty much the worst.

しかし、だからといって、自分の『自己肯定感』が揺らぐ、ということはありません。

However, this does not mean that my "self-esteem" will be shaken.

むしろ『他者否定感』を増大させます。

Rather, it increases the sense of denial of others.

つまり

It means,

―― 私は悪くない。世界が悪い

"It is not my fault but the world's fault"

です。

-----

私、メールの文面で、簡単に「カチン」と感じてしまう方です。

I'm the kind of person who gets easily "offended" by the text of an email.

ですから、こんな注意書きまで出しているくらいです。

That's why I even put out this warning.

とは言え、こんな注意書きに効果があるのは、利害関係にない人間だけです。

However, the only people who would benefit from such a warning are disinterested parties.

仕事においては、こんなことは日常茶飯事で、目くじらを立てていては、仕事になりません。

In my work, this kind of thing happens every day, and I can't do my job if I'm upset about it.

なぜなら、仕事とは、縦横無尽の面倒くさいリンクが張り巡らされたネットワークで成立しているからです。

This is because work is made up of a network of inexhaustible and tedious links.

その優位性は、仕事の内容で簡単にひっくり返ります。

That advantage can easily be turned upside down by the nature of the work.

具体的には、「動かせる"金"を、誰が持っているかどうか」で決まります。

Specifically, it depends on who has the "money" to make the move.

どんなに不愉快な奴でも、それが、いつか、自分にとっての"金主"になることがあります ―― 歳を取れば、こんなことは、日常的に、普通に、当たり前にあることが分かります(本当)。

No matter how unpleasant a person may be, he or she may one day become a "gold master" for you. As you get older, you realize that this is a normal, everyday thing.

-----

ですので、私の『アンガーマネージメント』は、腹が立った相手の顔を『札束』に見たてることです。

So, my "anger management" is to look at the face of the person I am angry with as a wad of cash.

私たちが相手にしているモノは、『人間』ではありません。

The thing we are dealing with is not a "human being".

あれは『札束』がしゃべっているのです。

The wad of cash is talking.

少なくとも私は、『札束』に対して、追従、忖度、甘受、従順、唯唯諾諾、土下座することに、1mmも抵抗はありません。

At least I don't have the slightest qualms about following, discerning, accepting, obeying, acquiescing, and getting down on my knees to "the wad of cash"

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

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,未分類,江端さんの技術メモ

これまで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

}

 

2021/11,江端さんの忘備録

(昨日の続きです)

(Continuation from yesterday)

以前の私なら、運転免許証の写真などを開示することには、もの凄い心理的抵抗がありました。

In the past, I would have had tremendous psychological resistance to disclosing things like my driver's license photo.

ワクチン接種証明書なんぞ、究極の個人情報です。

A vaccination certificate is the ultimate in personal information.

ですが、今の私は、かなり「どーでもよくなってきています」

But now I'm pretty sure I don't really care anymore.

実際、運転免許証とワクチン接種証明書の写真を送り込んで、アプリ登録を完了しています。

In fact, I sent in photos of my driver's license and vaccination certificate to complete the app registration.

(ただ、このアプリの提供するサービスを使う機会は、当面なさそうなのですが)

(However, I don't think I'll have the opportunity to use the services provided by this app in the foreseeable future.)

この情報が流出するようなことがあれば、もう、私の全ての個人情報が流出したのと同義でしょう。

If this information were to be leaked, it would be the equivalent of all my personal information being leaked.

-----

しかし、最近の私は、『個人情報の流出のリスク』よりも、『もっと便利で簡単な運用』の方に意識が向いています。

However, these days, I am more conscious of "more convenient and easier operation" rather than "risk of personal information leakage.

このようなアプリ登録は面倒なので、ワクチン接種証明は、とっととマイナンバーカードと紐付けて欲しいです。

Registering for such an application is a hassle, so I would like to see vaccination proof linked to my number card as soon as possible.

私の場合、カードリーダを自宅PCに接続していますが、今はスマホを使った読み込みもできるようなので、カードリーダーも不要でしょう。

In my case, I have a card reader connected to my home PC, but now I can use my phone to read the data, so I guess we don't need a card reader.

ワクチン接種ができない人の為に、PCR検査結果もマイナンバーカードとサクっと紐づけできるようにしておけば、有効期間経過後(例:3日後)に自動失効させるようにもできます。

For those who can't get vaccinated, PCR test results can also be quickly linked to the My Number Card, so that the card can be automatically revoked after its validity period (e.g., 3 days).

こうすれば、トラブルも少なくなりそうです。

This way, there will be less trouble.

ともあれ、私の『自分の個人情報を秘匿しようという意識』が薄れているのは事実です。

Anyway, it is true that my 'awareness of keeping my personal information confidential' is waning.

-----

私の個人情報の価値は、500円くらいなのでしょうが、ある一定の対象には、高値で取引される可能性があります。

The value of my personal information is probably about $500, but for certain targets, it could be worth a lot of money.

思いつくだけでも、「ビットコインの団体」「ダイエットの団体」「ネット詐欺の団体」「人工知能の団体」がありそうです。

Just off the top of my head, I can think of "Bitcoin groups," "diet groups," "internet scam groups," and "artificial intelligence groups.

あと「コロナワクチン拒否の団体または個人」は、私を直接狙うかもしれません。

Also, the "coronary vaccine rejecting groups or individuals" may target me directly.

いや、「命を狙う」てなことまでは考えないかもしれませんが、「自宅の庭に生ゴミを投げつけられる」くらいのことはされるかも、と覚悟はしています。

No, they may not think about "trying to kill me," but I am prepared for them to do something like "throwing garbage in my yard.

もしそういう事件が起ったら、みなさんに、直ぐにご報告します ―― 我が家の監視カメラの映像付きで。

If such an incident occurs, I'll let you all know right away -- with security camera video clip of my house.