蓝天,小湖,湖水中一方小筑

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)。