allMap存储的是一个任务列表,KEY标记了这个任务类型,Value对应的是任务的参数,现在我需要并发处理这些任务。开发过程中使用了如下两种方法,效果并不好,感觉自己没有领会到golang并发处理的思想;下面是我的几点体会和疑惑,希望得到各位大神的指导。方式一//allMap中存储了任务列表//Task定义如下typeTaskstruct{Paramsinterface{}ResultChanchan[]byte//Wg*sync.WaitGroup}Params是参数,ResultChan是处理完毕之后,将结果写入到ResultChan中;//并发处理任务forkey,value:=rangeallMap{gofunc(kstring,vinterface{}){log.Debug("k:",k)ifk==tools.REQUEST_BAOJIE{//Alog.Debug("baojieelemlen:",len(value))one_task=&service.Task{Params:v,ResultChan:make(chan[]byte,len(value)),//Wg:new(sync.WaitGroup),}//Blog.Debugf("1one_task:%+v",one_task)//AddTask函数逻辑会处理one_task,处理完毕之后,将结果写入到one_task结构体的ResultChan字段;service.AddTask(one_task)}elseifk==tools.REQUEST{}}(key,value)}//Clog.Debugf("2one_task:%+v",one_task)//接收结果gofunc(){foritem:=rangeone_task.ResultChan{log.Debug("ReceivedataFromResultChan:",string(item))}log.Debug("Process",tools.REQUEST_BAOJIE,"end")}()这种方式的弊端,太依赖程序执行的先后顺序了,测试的过程中,发现当C发生在A和B之前时,会使接收结果goroutinue访问ResultChan成员发生奔溃,因为此时ResultChan还没有申请空间。方案一解决方案:service.AddTask(one_task)函数再加一个参数,chan
2 回答

胡说叔叔
TA贡献1804条经验 获得超8个赞
想太多了,怕同时起多了协程,可以定义协程长度,更甚至采用协程池。简单写个实现:typetaskstruct{namestrigparamsinterface{}result[]byte}vargt=make(chanint,10)//同时只允许10个task一起执行vartkr=make(chantask,10)gofunc(){for_,t:=rangeallTaskMap{gt<-1gofunc(curtasktask){//处理task,tkr<-curtask//处理完,可以使用channel将结果传输出去<-gt//处理完毕退出}(t)}}()for{select{casert:=<-tkr://处理结果}}实际上很少用map去存储task列表,可以考虑使用channel传入task
添加回答
举报
0/150
提交
取消