参考ページ
http://gihyo.jp/dev/feature/01/go_4beginners/0005?page=3
URLの数だけゴルーチンを起動すると、メモリを圧迫する可能性があるため、 limitというバッファ付きのチャネルを用いて,このチャネルに値を書き込める場合は、 ゴルーチンを起動し,ゴルーチンが終わったらlimitから値を読み出すことで, ゴルーチンの同時起動数を制御してみます。 この場合,チャネルのバッファにあるデータの数が重要であり,データ自体には意味がないため, サイズがゼロの構造体を用います。 var empty struct{} // サイズがゼロの構造体 func getStatus(urls []string) <-chan string { statusChan := make(chan string, 3) // バッファを5に指定して生成 limit := make(chan struct{}, 5) go func() { for _, url := range urls { select { case limit <- empty: // limitに書き込みが可能な場合は取得処理を実施 go func(url string) { // このゴルーチンは同時に5つしか起動しない res, err := http.Get(url) if err != nil { log.Fatal(err) } statusChan <- res.Status // 終わったら1つ読み出して空きを作る <-limit }(url) } } }() return statusChan }
これは、
func getStatus(urls []string) <-chan string { statusChan := make(chan string, 3) // バッファを5に指定して生成 limit := make(chan bool, 5) go func() { for _, url := range urls { limit <- true go func(url string) { // このゴルーチンは同時に5つしか起動しない res, err := http.Get(url) if err != nil { log.Fatal(err) } statusChan <- res.Status // 終わったら1つ読み出して空きを作る <-limit }(url) } } }() return statusChan }
コードがおかしいかもしれないのですが、このようにforで回す度にlimit <- trueをし、終わったものから<-limitをすれば常時5つだけのクローリングになるかなと思ったのですが上の例と下の例は同じで良いのでしょうか?
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2020/01/19 03:39