怎样优雅的限制瞬时goruntine的个数
mozhata·2016-11-18 11:27:33·812次阅读·发布于 Go问答

假设有M个id,需要对每个id做一系列的操作,希望瞬时启动的goruntine只有N个(M > N)

怎样优雅的实现?

不需要频繁创建和销毁goroutine,创建一个goroutine池更合适。

package main import ( "fmt" "strconv" ) const ( WORKER_COUNT = 10 ID_COUNT = 100 ) type Message struct { id int result string } func main() { chId := make(chan int, WORKER_COUNT) chResult := make(chan Message, WORKER_COUNT) for i := 0; i < WORKER_COUNT; i++ { go func() { for { id := <-chId chResult <- Message{ id: id, result: strconv.Itoa(id), } } }() } go func() { for i := 0; i < ID_COUNT; i++ { chId <- i } }() for i := 0; i < ID_COUNT; i++ { msg := <-chResult fmt.Printf("id[%d]=>result[%s]\n", msg.id, msg.result) } }
2022-01-21 12:50:24

我没说明白,是这样的

有1万个id, 需要对每个id做一系列非常消耗资源的操作并返回一个结果,为了能让电脑正常工作,每时每刻启动的goruntine数量要限制在100以内,这是我能想到第最优雅的方式了

// 100个id,对每个id做一系列操作,并返回结果(对结果的顺序没有要求) func graceGoruntine() { const ( ID_NUM = 100 GORUNTINR_NUM = 10 ) result := make(chan string, GORUNTINR_NUM) work := func(id int, signal chan bool, result chan string) { str := strconv.Itoa(id) result <- str // 解除channel占用 <-signal } // 分发,处理任务 go func() { signal := make(chan bool, GORUNTINR_NUM) for i := 0; i < ID_NUM; i++ { signal <- true go work(i, signal, result) } }() // 处理返回的结果 idStrs := make([]string, 0, ID_NUM) for i := 0; i < ID_NUM; i++ { v := <-result idStrs = append(idStrs, v) } fmt.Printf("the result: %+v\n", idStrs) }
2022-01-21 12:50:24

下面的是伪代码,这里假设M是100,N是10:

var wg sync.WaitGroup func worker(id int, cochan chan struct{}) { // ... wg.Done() <-cochan } func main(){ wg.Add(100) ch:=make(struct{},10) for _, id := range ids { cochan <- struct{} go worker(id, cochan) } wg.Wait() }
2022-01-21 12:50:23

http://marcio.io/2015/07/handling-1-million-requests-per-minute-with-golang/ 这篇文章说的应该就是这么一个优化之路

2022-01-21 12:50:23
发起回帖
未登录,登录后可以回帖