Go並行処理   channel

ホーム   Goチュートリアル
目次


チャネルとは

goroutine を指定した関数は、戻り値を返すことができなくなります。そこでチャネル(channel、道筋)という機能を使って、goroutine を指定した関数からもデータを受け取れるようにします。

channel.go


package main

import (
	"fmt"
	"time"
)

func main() {

	fmt.Println("started")
	
	result := make(chan int)
	
	go times(44, result)
	go plus (44)
	
	fmt.Println(<- result)
	
	time.Sleep(time.Second * 2)
	fmt.Println("calculation is complete")
	time.Sleep(time.Second * 2)
	fmt.Println("finished")
}

func times(i int, result chan int) {
	time.Sleep(time.Second * 4)
	fmt.Printf("%d * %d = ", i, i)
	result <- i * i
}

func plus(i int) {
	time.Sleep(time.Second * 2)
	fmt.Printf("%d + %d = %4d\n", i, i, i+i)
}
	

実行結果


started
44 + 44 =   88
44 * 44 = 1936
calculation is complete
finished
	

コード説明


	result := make(chan int)
	
チャネルは参照型として取り扱います。make(chan 型) と記述することによって、チャネルのポインターを宣言できます。


	go times(44, result)
	go plus (44)
	

goroutine を指定した関数にも、引数は渡すことはできます。チャネルも引数として関数に渡します。


	fmt.Println(<- result)
	

チャネルにはデータの受け渡しをすることができます。チャネルからデータを受け取るには、<- チャネル名と記述します。ここで注意しなければいけないことは、関数側でチャネルにデータが渡されるまでは、ここで処理がストップするということです。


	time.Sleep(time.Second * 2)
	fmt.Println("calculation is complete")
	

スリープ時間を 2 秒に設定しています。しかし、チャネルにデータが入るまでは処理がストップしていますので、チャネルにデータが入るまでは、この処理が実行されることはありません。仮に、ここにスリープ時間を設定しなくても、処理が先に進んで main 関数が先に終わることはありません。


func times(i int, result chan int) {
	

チャネルを引数として受け取るには、変数名と型の間に chan と記述します。


	result <- i * i
	

チャネルにデータを渡すには、チャネル名 <- データと記述します。関数側でチャネルにデータを渡すまでは、データの受け取り側は処理をストップしています。


4549 visits
Posted: Jul. 04, 2019
Update: Jul. 05, 2019

ホーム   Goチュートリアル   目次