元ネタはmattnさんの記事から。
タイトルが goroutine の実行個数と言いながら goroutine 自体はいっぱい起動するのはこれ如何にという指摘を頂きましたが、ごもっともでタイトルバグですね。
追記にこう書かれているんですが、channel に詰めるタイミングを変えれば goroutine の数を制御できるのではないか?また sync.WaitGroup を使わなくても書けるのではないか?と考え、手を加えてみました。Go 言語は初心者ゆえ、間違いがありましたらご指摘いただけますと幸いです・・・!
package main
import (
"fmt"
"time"
)
func doSomething(u string) {
fmt.Println(u)
time.Sleep(2 * time.Second)
}
func main() {
urls := []string{
"http://www.example.com",
"http://www.example.net",
"http://www.example.net/foo",
"http://www.example.net/bar",
"http://www.example.net/baz",
}
limit := make(chan struct{}, 3)
for _, u := range urls {
// limit が一杯だとここで処理がブロックされる
limit <- struct{}{}
go func() {
doSomething(u)
// 終わったら limit をひとつ空ける
<-limit
}()
time.Sleep(200 * time.Millisecond)
}
// limit が埋まるまで = 最後の goroutine が終わるまで待つ
for i := 0; i < 3; i++ {
limit <- struct{}{}
}
}