版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 前言 有些朋友可能看我的这篇文章 简单的GOLANG 协程池 这是我做的简单协程池,功能还算完备,但是有些任务执行的时间很长,如果想在协程池运行起来以后就退出,就只能死等。这是非常不友好的,因此我又写了一个新的协程池GContextPool,利用context支持在任务运行过程中,结束任务。原来的GPool仍然可以继续使用。 下面我们来看看用法。
1. 安装 go get github.com/vearne/golib/utils 2. 使用 2.1 创建协程池 // 设定协程池的中协程的数量是30个 cxt, cancel := context.WithTimeout(context.Background(), 1 * time.Second) defer cancel() var p *utils.GContextPool = utils.NewGContextPool(ctx, 30) 2.2 定义任务处理函数 任务处理函数形如
type JobContextFunc func(ctx context.Context, key interface{}) *GPResult 执行任务
GContextPool.ApplyAsync(f JobContextFunc, slice []interface{}) f JobContextFunc 是目标函数 slice []interface{} 任务参数列表
示例 ctx_pool.go
package main import ( "context" "fmt" "github.com/vearne/golib/utils" "log" "strconv" "time" ) func JudgeStrWithContext2(ctx context.Context, key interface{}) *utils.GPResult { num, _ := strconv.Atoi(key.(string)) result := &utils.GPResult{} var canceled bool = false for i := 0; i < 60; i++ { select { case <-ctx.Done(): canceled = true result.Value = false result.Err = fmt.Errorf("normal termination") default: time.Sleep(time.Millisecond * 50) } } if !canceled { if num < 450 { result.Value = true } else { result.Value = false } } return result } func main() { cxt, cancel := context.WithTimeout(context.Background(), 1 * time.Second) defer cancel() p := utils.NewGContextPool(cxt,30) slice := make([]interface{}, 0) for i := 0; i < 1000; i++ { slice = append(slice, strconv.Itoa(i)) } result := make([]*utils.GPResult, 0, 10) trueCount := 0 falseCount := 0 start := time.Now() for item := range p.ApplyAsync(JudgeStrWithContext2, slice) { result = append(result, item) if item.Err!= nil{ //log.Println("cancel", item.Err) continue } if item.Value.(bool) { trueCount++ } else { falseCount++ } } log.Printf("cancel, %v, true:%v, false:%v, cost:%v\n", len(result), trueCount, falseCount, time.Since(start)) } 请我喝瓶饮料