LoginSignup
29
24

More than 5 years have passed since last update.

初心者がごるーちんでハマるところ

Last updated at Posted at 2015-12-08

概要

  • Go言語の特徴であるごるーちん(goroutine)。
  • go func_name()と書くだけで動くと聞いて、書いてみたけどうまくいかない!とハマったのでまとめました。
  • 結論: main()関数が終了するとごるーちんもすべて終了になるので、main()関数内にgo func_name()と書くだけではごるーちんが起動前にプログラム自体が死んでしまいます。解決するには、チャネルを使う方法があります。サンプルは下に。

うまくいかない例

  • ↑リンク先の「Run」ボタンを押すとプログラムが実行されます
goroutine_NG.go
package main

import (
    "log"
    "time"
)

func sub() {
    log.Println("ごるーちんが呼ばれたよ!")
    time.Sleep(3 * time.Second)
    log.Println("3秒経過!")
}

func main() {
    log.Println("--- main start ---")

    // ごるーちんの呼び出し(うまくいかない)
    go sub()

    log.Println("--- main finish ---")
}

実行結果

  • ごるーちんが実行されない
2009/11/10 23:00:00 --- main start ---
2009/11/10 23:00:00 --- main finish ---

なんでごるーちんすぐ死んでしまうん?

  • main()が終了するとすべてのプロセス(goroutineで呼び出したファンクション含む)が終了するから
  • 上記だとごるーちんを呼び出した直後にmain()が終了しているためごるーちんが実行されません
  • ごるーちんの終了を待ってからmain()を終了する必要があります

チャネルを使ってごるーちんの終了を待つ例

  • ↑リンク先の「Run」ボタンを押すとプログラムが実行されます
goroutine_SUCCESS.go
package main

import (
    "log"
    "time"
)

func sub(ch chan bool) {
    log.Println("ごるーちんが呼ばれたよ!")
    time.Sleep(3 * time.Second)
    log.Println("3秒経過!")

    // 処理が終わったらチャネルに通知
    ch <- true
}

func main() {
    log.Println("--- main start ---")

    // チャネル作成
    ch1 := make(chan bool)

    // ごるーちんの呼び出し
    go sub(ch1)

    // チャネルから通知が届くのを待つ
    <-ch1

    log.Println("--- main finish ---")
}

実行結果

  • ごるーちんで呼び出したファンクションが無事実行されました
2009/11/10 23:00:00 --- main start ---
2009/11/10 23:00:00 ごるーちんが呼ばれたよ!
2009/11/10 23:00:03 3秒経過!
2009/11/10 23:00:03 --- main finish ---
  • チャネルを知らない段階で、とりあえずごるーちん動かそうぜ!と思うとこの解決法が思い浮かばずハマりました。
  • で、チャネルって何さという点についてはGo その3 1日目の記事がサンプルもあって非常に参考になります!

その他

29
24
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
29
24