2017-08-17 3 views
0

私はゴランの並行性を学び、URLを順番に表示するプログラムを書いています。 *** /google.com:私は、コードが
http://bing.com* http://google.com *ゴラン同時実行問題

を返すことを期待しかし、それは常にHTTPを返します。変数が上書きされているかのように.Goroutinesを使用しているので、私は両方の値をsametimeで返すと期待しています。

func check(u string) string { 
tmpres := u+"*****" 
return tmpres 
} 

func IsReachable(url string) string { 
ch := make(chan string, 1) 
go func() { 

    ch <- check(url) 

    }() 
select { 
case reachable := <-ch: 
    // use err and reply 
    return reachable 
case <-time.After(3* time.Second): 
    // call timed out 
    return "none" 
} 
    } 



func main() { 

var urls = []string{ 
    "http://bing.com/", 
    "http://google.com/", 
} 

for _, url := range urls { 
    go func() { 
    fmt.Println(IsReachable(url)) 
    }() 
} 
time.Sleep(1 * time.Second) 
    } 

答えて

5

2つの問題。まず、競合状態を作成しました。ループ変数を閉じると、ループを実行しているスレッドとgoroutineを実行しているスレッドとの間で共有されているため、問題が発生します。最初のURLで開始されたgoroutineが実行されるまでに、変数の値が変更されました。あなたはどちらか例えば、ローカル変数にコピー、または引数として渡す必要があります。

for _, url := range urls { 
    go func(url string) { 
    fmt.Println(IsReachable(url)) 
    }(url) 
} 

第二に、あなたは目標は、一般的に、並行性と互換性がありません。これは、あなたが「順番に」それらを表示したいと述べましたパラレル操作の順序を制御することはできないためです。それらを順番に使用したい場合は、1つのスレッドで順番に実行する必要があります。それ以外の場合は、結果を収集し、すべての回答が返ってくるまで待ってから、結果を希望の順序に並べ替えてから印刷してください。

+0

返信いただきありがとうございます、それは問題を解決しました。注文する代わりに、私は文字列を連結します、これは私のプログラムの残りの部分を助けるでしょう。 Iamは現在、チャンネルに値を取ることでそれをやっています:test:= IsReachable(url)message < - テストし、最後にforループを使ってテストします。同じことをするより良い方法はありますか? for i:= 1; i <= len(urls);これが最適なプログラミングであるかどうかを知るためにはうまく働いています。ヘルプを評価してください。 – ChrisDave

関連する問題