2017-07-03 12 views
0

オンラインチュートリアル「Goのツアー」に従って、私は勉強しています。このエクササイズでなぜサブルーチンが実行されないのですか

:問題を解決するために行く前にhttps://tour.golang.org/concurrency/10

、私はシンプルなものを試してみたかった:

func Crawl(url string, depth int, fetcher Fetcher) { 
    fmt.Println("Hello from Crawl") 
    if depth <= 0 { 
     return 
    } 
    body, urls, err := fetcher.Fetch(url) 
    if err != nil { 
     fmt.Println(err) 
     return 
    } 
    fmt.Printf("found: %s %q\n", url, body) 
    for _, u := range urls { 
     fmt.Println("in loop with u = %s", u) 
     go Crawl(u, depth-1, fetcher) //I added "go" here 
    } 
} 

私は追加唯一のものは、右の再帰呼び出しの前goコマンドですCrawl。私はそれが行動に大きく変わるべきではないと思った。

Hello from Crawl 
found: http://golang.org/ "The Go Programming Language" 
in loop with u = http://golang.org/pkg/ 
in loop with u = http://golang.org/cmd/ 

私はループの反復ごとにHello from Crawlが見込ま:プリントアウトがあるしかし

Crawlサブルーチンが実行されないのはなぜですか?

+0

は、私はそのリンクされた質問の答え鉱山にも同意します。 –

答えて

2

あなたのゴルーチンは開始しましたが、あなたのmain()が終了したため、あなたのやりたいことをする前に終了しました。 goroutinesの実行は、スレッドのようなメインプログラムとは独立していますが、プログラムが停止すると終了します。したがって、ゴルーチンが仕事を終えるのを待つためにはWaitGroupが必要です。または、メインプログラムをしばらくの間スリープさせるには、単にtime.Sleep()を呼び出してください。

+0

チュートリアルではまだWaitGroupをカバーしていませんでしたが、少なくとも私は今問題を理解していて、お互いに感謝します。 –

+0

あなたはWaitGroupの代わりにチャンネルを使うことができます。ここの本質は、あなたがルーチンを完了するのを待つ必要があるという事実です。 –

+0

@NathanHあなたは歓迎しています。 – jfly

1

すべてのゴールーチンは、プログラムが終了する前に終了していることを確認するためには何もありませんが、私はこれに似たものに、あなたのコードをリファクタリングしたい:

func Crawl(url string, depth int, fetcher Fetcher) { 
    fmt.Println("Hello from Crawl") 
    if depth <= 0 { 
     return 
    } 
    body, urls, err := fetcher.Fetch(url) 
    if err != nil { 
     fmt.Println(err) 
     return 
    } 
    fmt.Printf("found: %s %q\n", url, body) 
    // Adding waiting group to make sure go routines finishes 
    wg := sync.WaitGroup{} 
    wg.Add(len(urls)) 
    for _, u := range urls { 
     fmt.Println("in loop with u = %s", u) 
     go func() { 
      defer wg.Done() 
      Crawl(u, depth-1, fetcher) 
     }() 
    } 
    wg.Wait() 
} 
関連する問題