goroutineとchannel入門

created byTakuya Ueda. Licensed under the Creative Commons 3.0 Attributions license.

こんにちはnasustです。 今回はgoroutineとchannelの入門記事です。

これらはGo言語 / golangに組み込まれたスレッドの機能です。 この機能を利用することにより、簡単に安全なスレッドを扱う事が出来ます。

スレッドとは

スレッドとは並列処理を行うものです。 乱暴に解説しますと、スクリプトでマルチプロセス処理していたものを、1つのプロセスで並列処理を行う事が出来ます。マルチプロセスよりコンテキストを小さくできるので処理が速くなる可能性あります。また1つのプログラムになるのでメモリも節約できる可能性があります。

ただし、マルチプロセスには無い危険な操作など出来るようになります。並列処理中に1つの変数を同時に書き込んだり、読み込んだりすると意図しない動作になることがあります。

これは、同時に書き込むことにより結果が不定になる為です。

Go言語 / golangでは、その問題を防ぐ機能としてchannelなどあります。

channel

channelの作成は以下の構文です。

make(chan T , buf)
go

T型の値をchannelを使用してスレッド側と通信できます。 bufはバッファーの数を指定します。省略が可能で、省略時はバッファーなしになります。

例:

スレッドで時間が掛かる処理の場合のコードです。

package main

import (
	"fmt"
	"time"
)

func main() {
	c := make(chan int)

	go func() {//何か時間がかかる処理
		time.Sleep(5 * time.Second)
		c <- 5
	}()

	num := <-c

	fmt.Println("go:", num)
}
go

c <- 5が送信で、num := <-cが受信です。

例:

逆にメインスレッドで時間が掛かる例です。

package main

import (
	"fmt"
	"time"
)

func main() {
	c := make(chan int)

	go func() {
		num := <-c
		fmt.Println("thread: ", num)
	}()

	time.Sleep(5 * time.Second)
	c <- 5
	time.Sleep(1 * time.Second)
}
go

まとめ

channelを使用して、スレッド間をソケットの様に送信受信することによって、変数の同時アクセスを防ぐ機能が、このようにあります。

このようにGo言語 / golangでは簡単にスレッド間通信が出来ます。

prevnext