Go 入門

Go言語入門⑮ ~channelのrangeとclose・producerとconsumer・fan-out,fan-in~

[box class="blue_box" title="☑本記事の内容"]

  • channelのrangeとclose
  • producerとconsumer
  • fan-out,fan-in

[/box]
参考資料:現役シリコンバレーエンジニアが教えるGo入門 + 応用でビットコインのシストレFintechアプリの開発
[box class="glay_box" title="Contents"]

  1. Go入門-channelのrangeとclose-
  2. Go入門-producerとconsumer-
  3. Go入門-fan-out,fan-in-

[/box]

Go入門-channelのrangeとclose-

[box class="glay_box"]

  • channelをその都度出力する方法
  • rangeを使用した際は、関数の方にcloseを使用する

[/box]

package main

import "fmt"

func goroutine1(s []int, c chan int) {
	sum := 0
	for _, v := range s {
		sum += v
		c <- sum
	}
	close(c)
}

func main() {
	s := []int{1, 2, 3, 4, 5}
	c := make(chan int, len(s))
	go goroutine1(s, c)
	for i := range c {
		fmt.Println(i)
	}
}
(結果)
1
3
6
10
15

Go入門-producerとconsumer-

producer

[box class="glay_box"]

  • 様々な処理を並列で行う処理
  • 例としては色々なサーバーに行きlogを取ってきて解析したりする
  • 処理が終わったらchannelに値を送信する

[/box]

consumer

[box class="glay_box"]

  • channelから受け取った値を処理する

[/box]
Go入門-producerとconsumer-

処理参考図1

[box class="glay_box"]

  • goroutineなので最後にcloseをする必要がある

[/box]

package main

import (
	"fmt"
	"sync"
)

func producer(ch chan int, i int) {
	ch <- i * 2
}

func consumer(ch chan int, wg *sync.WaitGroup) {
	for i := range ch {
		fmt.Println("process", i*1000)
		wg.Done()
	}
}

func main() {
	var wg sync.WaitGroup
	ch := make(chan int)

	for i := 0; i < 10; i++ {
		wg.Add(1)
		go producer(ch, i)
	}

	go consumer(ch, &wg)
	wg.Wait()
	close(ch)
}
(結果)
process 0
process 2000
process 4000
process 6000
process 8000
process 10000
process 12000
process 14000
process 16000
process 18000

Go入門-fan-out,fan-in-

[box class="glay_box"]

  • goroutineを使用して結果を渡すことをfan-out、受け取ることをfan-inという
  • 処理を分けることでどんな処理をしているか把握しやすくなる

[/box]
Go入門-fan-out,fan-in-

処理参考図2

package main

import "fmt"

func producer(first chan int) {
	defer close(first)
	for i := 0; i < 10; i++ {
		first <- i
	}
}

func multi2(first <-chan int, second chan<- int) {
	defer close(second)
	for i := range first {
		second <- i * 2
	}
}

func multi4(second chan int, third chan int) {
	defer close(third)
	for i := range second {
		third <- i * 4
	}
}

func main() {
	first := make(chan int)
	second := make(chan int)
	third := make(chan int)

	go producer(first)
	go multi2(first, second)
	go multi4(second, third)
	for result := range third {
		fmt.Println(result)
	}
}
(結果)
0
8
16
24
32
40
48
56
64
72

Go言語入門⑯へ ≫

≪ Go言語入門⑭へ

目次

-Go, 入門