需求
一个接口调用时,接收到一个列表,十个元素,需要并发执行十个任务,每个任务都要返回执行的结果和异常,然后对返回的结果装填到一个切片列表里,统一返回结果。
需要协程处理的结构体
type Order struct { Name string `json:"name"` Id int `json:"id"` }
确定通道数量
一般按入参的需要处理的元素数量为准
taskNum:=10
初始化通道
orderCh := make(chan Order, taskNum) //接收返回的结果 errCh:=make(chanerror,taskNum)//接收返回的异常
发起执行,我们使用sync.WaitGroup来监听执行情况
wg := sync.WaitGroup{} for i:=0; i < taskNum; i++ { wg.Add(1) go func() { defer wg.Done() if i == 3 {//模拟当i=3的时候,返回一个异常 err := errors.New("there is an error") errCh <- err return } //组装返回结果 res := Order{ Name: "num: " + strconv.Itoa(i), Id: i, } orderCh <- res }() } wg.Wait() //等待所有任务执行完毕
使用for-select接收执行结果
orderList := make([]Order, taskNum) for i:=0; i1,超时问题
任务执行过程中,需要控制每个任务的执行时间,不能超过一定范围,我们用定时器来解决这个问题
timeoutTime := time.Second * 3 //超时时间 taskTimer := time.NewTimer(timeoutTime) //初始化定时器 orderList := make([]Order, taskNum) for i:=0; i2, 协程panic问题
主程序是无法捕捉协程内的panic,因此如果不手动处理,就会发生协程内panic导致整个程序中止的情况,我们在defer里处理
for i:=0; i < taskNum; i++ { wg.Add(1) go func() { defer func () { wg.Done() //协程内单独捕捉异常 if r := recover(); r != nil { err := errors.New(fmt.Sprintf("System panic:%v", r)) errCh <- err //此处将panic信息转为err返回,也可以按需求和异常等级进行处理 return } }() ........ }() }3, 顺序问题
返回的列表元素的顺序,需要跟传参的列表顺序保持一致,这时我们需要定义个带序号的结构体
// 需要记录原始顺序的时候,定义个带编号的结构体 type OrderWithSeq struct { Seq int OrderItem Order } //重写相关排序类型 type BySeq []OrderWithSeq func (a BySeq) Len() int { return len(a) } func (a BySeq) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a BySeq) Less(i, j int) bool { return a[i].Seq < a[j].Seq } // 调整返回结果 orderCh := make(chan OrderWithSeq, taskNum) //接收带序号的结构体 //在执行任务时,加入序号 for i:=0; i < taskNum; i++ { i:= i wg.Add(1) go func() { ···· //组装返回结果 res := Order{ Name: "num: " + strconv.Itoa(i), Id: i, } orderCh <-OrderWithSeq { Seq: i, //带上i这个序号 OrderItem: res, } }() //接收信息,也按带序号的结构体进行组装 orderSeqList := make([]OrderWithSeq, taskNum) for i:=0; i总结
标准模板如下:
type Order struct { Name string `json:"name"` Id int `json:"id"` } // 需要记录原始顺序的时候,定义个带编号的结构体 type OrderWithSeq struct { Seq int OrderItem Order } //重写相关排序类型 type BySeq []OrderWithSeq func (a BySeq) Len() int { return len(a) } func (a BySeq) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a BySeq) Less(i, j int) bool { return a[i].Seq < a[j].Seq } taskNum := 10 orderCh := make(chan OrderWithSeq, taskNum) //接收带序号的结构体 errCh := make(chan error, taskNum) //接收返回的异常 wg := sync.WaitGroup{} //在执行任务时,加入序号 for i:=0; i < taskNum; i++ { i:= i wg.Add(1) go func() { defer func () { wg.Done() //协程内单独捕捉异常 if r := recover(); r != nil { err := errors.New(fmt.Sprintf("System panic:%v", r)) errCh <- err //此处将panic信息转为err返回,也可以按需求和异常等级进行处理 return } }() //组装返回结果 res := Order{ Name: "num: " + strconv.Itoa(i), Id: i, } orderCh <-OrderWithSeq { Seq: i, //带上i这个序号 OrderItem: res, } }() wg.Wait() //接收信息,也按带序号的结构体进行组装 orderSeqList := make([]OrderWithSeq, taskNum) timeoutTime := time.Second * 3 taskTimer := time.NewTimer(timeoutTime) for i:=0; i
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
-
接口
+关注
关注
33文章
7640浏览量
148509 -
定时器
+关注
关注
23文章
3148浏览量
112041
原文标题:总结
文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
请问一个协调器连接十个终端,如何能获取十个终端的短地址?
本帖最后由 一只耳朵怪 于 2018-5-24 14:22 编辑
一个协调器连接十个终端,如何能获取十个终端的短地址,求思路
发表于 05-22 08:57
十个练习让你学会Verilog语言
10个 Verilog 练习,进阶级教程 完整的pdf格式文档电子发烧友下载地址(共26页): 十个练习让你学会Verilog语言.pdf
发表于 07-03 02:04
arduino学习必须掌握的十个函数
必须掌握的函数,一共只有十个,所以一定要记住,没有什么难的1.数字输入输出I/O·① pinMode(pin, mode) 说明:数字IO 口输入输出模式定义函数,pin 表示为0~13, mode
发表于 07-19 09:47
串口发送数据超过十个数据就出现数据丢失
自己编写的程序,给串口1发送数据,然后串口1再发回主机,但是出现个问题,只能发十个数据,超过十个就出现数据丢失,代码哪里出错了呢?
发表于 01-29 07:35
mini板下载ucosii调用三个任务只有一个程序在执行是为什么?
在mini板上用ucos操作系统调用了三个任务分别是跑马灯、DHT11测温湿度、BMP180测气压,发现程序只全程执行了一次就停住了,有人遇到过这种情况吗??程序代码如下:(串口打印出
发表于 05-15 00:52
ECG十个电极和12导联
ECG十个电极和12导联1.对ECG获取心电图信息不是很了解,ECG只有十个电极为什么称作12导联?电极和导联之间有什么关联?2.什么叫做右脚驱动?为什么不能用左脚?3.除了PPG、ECG、还有BCG技术,如果做心率的检测用哪种技术更好?
发表于 12-08 16:31
微机原理与接口技术知识总结
系统总线:数据总线(双向)、地址总线(单向)、控制总线冯·诺依曼关于程序存储的原则:指令和数据预先存放在内存中bit为二进制位,8bit=1字节,1字=2字节BCD码:用4位二进制数来表示1位十进制数中0~9这十个数8086CPU:数据总线16位,地址总线20位,最
发表于 12-10 06:07
HarmonyOS如何使用异步并发能力进行开发
UI的同时,后台也能执行耗时操作,从而避免应用出现卡顿。
并发能力在多种场景中都有应用,其中包括单次I/O任务、CPU密集型任务、I/O密集型任务
发表于 09-22 17:35
Dispatch Queue任务执行与Dispatch Source
导读本文为读《Concurrency Programming Guide》笔记第三篇,在对OS X和iOS应用开发中实现任务异步执行的技术、注意事项、Operation与Dispatch
发表于 10-11 11:54
•0次下载
评论