Skip to main content

Get full access to 実用 Go言語 ―システム開発の現場で知っておきたいアドバイス and 60K+ other titles, with a free 10-day trial of O'Reilly.

There are also live events, courses curated by job role, and more.

16.5 ゴルーチン間のイベント伝達

チャネルはゴルーチンセーフなデータ構造で、送信元から受信先へ「データ」を伝達します。しかし、何かしらのデータではなく「何かが発生した」というイベントだけを通知したいことがあります。たとえばタスクが完了したという通知などです。Goのライブラリでは、サイズゼロの空の構造体を使ったチャネルがよく利用されています。

	// ゼロバイトの構造体のチャネル
	wait := make(chan struct{})

	// 受信
	<-wait

このチャネルを使って通知する場合には、空の構造体のインスタンスを送ります。

	// 送信
	wait <- struct{}{}

上記のようにイベントを送信すると、イベントを受信する複数のゴルーチンのうち、1つだけがイベントを受け取れます。複数のチャネルへイベントをブロードキャストしたい、かつそのイベントが1度だけ発生する場合には、チャネルをクローズする方法があります。

	// 送信の代わりにクローズ
	close(wait)

チャネルをクローズすると、同じチャネルを監視しているすべてのゴルーチンへ一斉に通知が行きます。これはイベントをブロードキャストしているのと同じ効果があります。一度クローズしたあと、そのチャネルへ再度読み込みに行こうとするとブロックせずにゼロ値が返ります。

チャネルの送信を用いて通知を行うと、1つの相手に1件のみ厳密に伝わります。相手が見えているのであればチャネルの送信でも良いですが、ささいなミスでブロッキングし続けることもあるため、クローズの方が安心です。

チャネルは誰も参照しなくなれば、クローズしなくてもガベージコレクタに回収されますが、たとえば、どこかのゴルーチンで読み込みを続けていると、それがブロックされ続けて、チャネルリークの原因となります。 ...

Get 実用 Go言語 ―システム開発の現場で知っておきたいアドバイス now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.

Don’t leave empty-handed

Get Mark Richards’s Software Architecture Patterns ebook to better understand how to design components—and how they should interact.

It’s yours, free.

Get it now
Cover of Software Architecture Patterns

Check it out now on O’Reilly

Dive in for free with a 10-day trial of the O’Reilly learning platform—then explore all the other resources our members count on to build skills and solve problems every day.

Start your free trial Become a member now