LoginSignup
0
0

More than 3 years have passed since last update.

go修行12日目 channelなど

Posted at

channel

package main

import "fmt"

// SlieceとChannelを扱う関数
func gorooutine1(s []int, c chan int) {
    sum := 0
    for _, v := range s {
        sum += v
    }
    // <- Channelに送信
    c <- sum
}

func main() {
    s := []int{1, 2, 3, 4, 5}
    // channel integerを扱う
    c := make(chan int)
    go gorooutine1(s, c)
    // <- c でChannelから受け取るまで待機
    x := <-c
    fmt.Println(x)
}

15

キューのような使い方

  • 2つのチャンネルを並列実行しても2つの処理の実行を待つ

package main

import "fmt"

// SlieceとChannelを扱う関数
func gorooutine1(s []int, c chan int) {
    sum := 0
    for _, v := range s {
        sum += v
    }
    // <- Channelに送信
    c <- sum
}

func gorooutine2(s []int, c chan int) {
    sum := 0
    for _, v := range s {
        sum += v
    }
    // <- Channelに送信
    c <- sum
}

func main() {
    s := []int{1, 2, 3, 4, 5}
    // channel integerを扱う
    c := make(chan int)
    go gorooutine1(s, c)
    go gorooutine2(s, c)
    // <- c でChannelから受け取るまで待機
    x := <-c
    fmt.Println(x)
    y := <-c
    fmt.Println(y)
}
15
15

Bufferd channel


package main

import "fmt"

func main() {
    ch := make(chan int, 2)
    ch <- 100
    fmt.Println(len(ch))
    ch <- 200
    fmt.Println(len(ch))
    // rangeで呼び出す場合はcloseしないと次のChannelを呼ぼうとしてエラーになる
    close(ch)

    // forで1つづつ呼び出す
    for c := range ch {
        fmt.Println(c)
    }
}
1
2
100
200

channelのrange、Close


package main

import "fmt"

func goroutine1(s []int, c chan int) {
    sum := 0
    for _, v := range s {
        sum += v
        c <- sum
    }
    // 処理完了後はcloseを入れる
    close(c)
}

func main() {
    s := []int{1, 2, 3, 4, 5}
    c := make(chan int, len(s))
    go goroutine1(s, c)
    // channelを1回ずつ呼び出す
    for i := range c {
        fmt.Println(i)
    }
}
1
3
6
10
15

Producer Consumer


package main

import (
    "fmt"
    "sync"
    "time"
)

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

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

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

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

    // Consumer
    go consumer(ch, &wg)
    wg.Wait()
    close(ch)
    time.Sleep(2 * time.Second)
    fmt.Println("Done")
}
process 0
process 4000
process 2000
process 6000
process 8000
process 10000
process 12000
process 14000
process 16000
process 18000
#################################
Done

fan-out fan-in


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 {
        // 1 * 2 = 2
        // 2 * 2 = 4
        second <- i * 2
    }
}

func multi4(second chan int, third chan int) {
    defer close(third)
    for i := range second {
        // 2 * 4 = 8
        // 4 * 4 = 4
        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

select


package main

import (
    "fmt"
    "time"
)

func goroutine1(ch chan string) {
    for {
        ch <- "packat from 1"
        time.Sleep(3 * time.Second)
    }
}

func goroutine2(ch chan string) {
    for {
        ch <- "packat from 2"
        time.Sleep(1 * time.Second)
    }
}

func main() {
    c1 := make(chan string)
    c2 := make(chan string)
    go goroutine1(c1)
    go goroutine2(c2)

    for {
        select {
        case msg1 := <-c1:
            fmt.Println(msg1)
        case msg2 := <-c2:
            fmt.Println(msg2)
        }
    }
}
packat from 1
packat from 2
packat from 2
packat from 2
packat from 1
packat from 2
packat from 2
packat from 2

Default Section


package main

import (
    "fmt"
    "time"
)

func main() {
    tick := time.Tick(100 * time.Millisecond)
    boom := time.After(500 * time.Millisecond)

    for {
        select {
        // 100Millisocond毎
        case <-tick:
            fmt.Println("tick,")
            // 500Millisocond毎
        case <-boom:
            fmt.Println("BOOM")
            // loop終了
            return
            // それ以外はピリオド
        default:
            fmt.Println("    .")
            time.Sleep(50 * time.Millisecond)
        }
    }
}
    .
    .
tick,
    .
    .
tick,
    .
    .
tick,
    .
    .
tick,
    .
    .
tick,
BOOM
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