Control Goroutines amount via bufferred channel
最近还是在写爬虫,然后发现用goroutine是很快,但是很容易就碰到并发数过多被服务器限制的问题。虽然说让goroutine在起来前睡一小会能解决一些问题
,但是终归感觉这样的办法不靠谱。继续翻文档发现bufferred channel
用在这不错。
Bufferred Channel
Bufferred channel
和前一篇文章中说的东西没
有太大差别,只是那篇文章中说的channel是不带缓存的,也就是相当于Semaphore的用法,而加了缓存的就是管道。不多说了,直接上代码吧:
package main
import "fmt"
import "time"
func main() {
channel_cnt := 10
concurrency_chan := make(chan bool, 2)
msg_chan := make(chan string)
fmt.Println("Start launching goroutines")
for i := 0; i < channel_cnt; i++ {
go foo(i, concurrency_chan, msg_chan)
}
fmt.Println("Finish launching goroutines")
for i := 0; i < channel_cnt; i++ {
fmt.Println(<-msg_chan)
}
}
func foo(i int, concurrency_chan chan bool, msg_chan chan string) {
concurrency_chan <- true
s := fmt.Sprintf("%s: Call index %d", time.Now(), i)
msg_chan <- s
time.Sleep(1 * time.Second)
<-concurrency_chan
}
这段程序创建了两个channel
,而concurrency_chan
就是一个用来控制goroutine数量的channel
。在每个gorout ine
开始的时候,会往这个channel
中写入一个值,而在函数结束的时候从channel
中把东西取出来。当channel
中的缓存被占满的时候,
后续的写入请求就会被阻塞,从而达到限制goroutine
个数的目的。代码和输出结果可以看[这里](http://play.golang.org/p/8-
qUxtH0gp)。