LoginSignup
0
0

More than 3 years have passed since last update.

[Golang]goroutineを使った並行処理が、めっちゃシンプルにかける件

Last updated at Posted at 2019-08-13

お急ぎの方へ いきなりサンプルコード

並行処理のサンプルコード
package main

import (
    "fmt"
    "time"
)

func task1() {
    fmt.Println("task1 処理開始")
    for i := 0; i < 3; i++{
        time.Sleep(time.Second * 2)
        fmt.Printf("task1 %d/3 処理済み...\n", i+1)
    }
    fmt.Println("task1 処理終了")
}

func task2() {
    fmt.Println("task2 処理開始")
    for i := 0; i < 5; i++{
        time.Sleep(time.Second * 1)
        fmt.Printf("task2 %d/5 処理済み...\n", i+1)
    }
    fmt.Println("task2 処理終了")
}

func main() {
    fmt.Println("main 処理開始")
    go task1()
    go task2()
    time.Sleep(time.Second * 8)
    fmt.Println("main 処理終了")
}

非並行処理の場合

コード

並行処理のサンプルコード
package main

import (
    "fmt"
    "time"
)

func task1() {
    fmt.Println("task1 処理開始")
    for i := 0; i < 3; i++{
        time.Sleep(time.Second * 2)
        fmt.Printf("task1 %d/3 処理済み...\n", i+1)
    }
    fmt.Println("task1 処理終了")
}

func task2() {
    fmt.Println("task2 処理開始")
    for i := 0; i < 5; i++{
        time.Sleep(time.Second * 1)
        fmt.Printf("task2 %d/5 処理済み...\n", i+1)
    }
    fmt.Println("task2 処理終了")
}

func main() {
    fmt.Println("main 処理開始")
    task1()
    task2()
    fmt.Println("main 処理終了")
}

解説

とても簡単なコードです。

  • スリープで時間を区切りながら、forループで回している
  • task1メソッドとtask2メソッドは、それぞれ違う回数のループ、違う時間のスリープに設定

非並行処理の場合は、当然毎回毎回スリープに引っかかりつつも、1つずつ処理を終わらせて、次の処理に入っている様子が分かるかと思います。

非並行処理パターン実行の様子

画面収録 2019-08-13 18.07.17.mov.gif

並行処理の場合

コード

並行処理のサンプルコード
package main

import (
    "fmt"
    "time"
)

func task1() {
    fmt.Println("task1 処理開始")
    for i := 0; i < 3; i++{
        time.Sleep(time.Second * 2)
        fmt.Printf("task1 %d/3 処理済み...\n", i+1)
    }
    fmt.Println("task1 処理終了")
}

func task2() {
    fmt.Println("task2 処理開始")
    for i := 0; i < 5; i++{
        time.Sleep(time.Second * 1)
        fmt.Printf("task2 %d/5 処理済み...\n", i+1)
    }
    fmt.Println("task2 処理終了")
}

func main() {
    fmt.Println("main 処理開始")
    go task1()
    go task2()
    time.Sleep(time.Second * 8)
    fmt.Println("main 処理終了")
}

解説

内容としては、先ほどとほぼ同じ…

  • スリープで時間を区切りながら、forループで回している
  • task1メソッドとtask2メソッドは、それぞれ違う回数のループ、違う時間のスリープに設定

こんな感じです。

しかし、並行処理の場合は、main処理の中にgoという記述がしてあります。
これによって、task1とtask2、そしてmainは並行して処理が行われます。

当然、毎回毎回スリープに引っかかるのですが、3手に別れてそれぞれが処理を終わらせていっているので、実行結果が入り乱れているのが分かるかと思います。

並行処理実行の様子

画面収録 2019-08-13 18.08.52.mov.gif

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