0
0

【Go言語学習】チャネル( Channel )

Last updated at Posted at 2024-05-07

A Tour of Goでの説明

Channels
チャネル( Channel )型は、チャネルオペレータの <- を用いて値の送受信ができる通り道です。
https://go-tour-jp.appspot.com/concurrency/2

ゴルーチン間で値のやり取り

ゴルーチンは非同期だけど、チャネルを使って同期させる。
情報処理検定で出てくる、キュー(先入れ先出し、FIFO)の動作。最初にチャネルに送信したデータが最初に受信される。スタック(後入れ先出し、LIFO)ではないイメージ。
mainゴルーチンの最後にチャネル受信を用意しておくと、全終了を待たせることができる。

デットロック

チャネルへの送信操作は、そのデータが受信されるまでゴルーチンをブロックするため、同じゴルーチン内でチャネルの送受信を行うとデッドロックが発生する。→バッファ付きチャネルを使用すれば解消する。

試してみた

package main

import (
	"fmt"
	"time"
)

func main() {
	ch1 := make(chan int)
	ch2 := make(chan int)

	go func() {
		time.Sleep(5 * time.Second) // 二秒
		ch1 <- 1
	}()

	go func() {
		time.Sleep(3 * time.Second) //一秒
		ch2 <- 2
	}()

	for i := 0; i < 2; i++ {
		select { //コードの記載順序に関係なく、先に到達した方が実行される
		case x := <-ch1:
			fmt.Println(x)
		case y := <-ch2:
			fmt.Println(y)
		}
	}
}

/* A Tour of Goのselect
package main

import "fmt"

func fibonacci(c, quit chan int) {
	x, y := 0, 1
	for { //3.無限ループ
		select {
		case c <- x: //4.ここで1に値が送られる、10回繰り返す
			x, y = y, x+y
		case <-quit:
			fmt.Println("quit")
			return
		}
	}
}

func main() {
	c := make(chan int)
	quit := make(chan int)
	go func() {
		for i := 0; i < 10; i++ {
			fmt.Println(<-c) //1.ここでいったん止まり、2が実行され、10回送られてきた後、forを抜ける
		}
		quit <- 0 //5.2の呼び出しを終了させる
	}()
	fibonacci(c, quit) //2.呼び出す
}

*/

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0