完整的golang 多协程+信道 任务处理示例
时间:2022-05-05
本文章向大家介绍完整的golang 多协程+信道 任务处理示例,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
Go
package mainimport ( "sync"
"fmt")/*
一个标准的协程+信道实现
*/func main() {
taskChan := make(chan int)
TCount := 10
var wg sync.WaitGroup //创建一个sync.WaitGroup
// 产生任务
go func() { for i := 0; i < 1000; i++ {
taskChan <- i
} // 全部任务都输入后关闭信道,告诉工作者进程没有新任务了。
close(taskChan)
}() // 启动 TCount 个协程执行任务
wg.Add(TCount) for i := 0; i < TCount; i++ { // 注意:如果协程内使用了 i,必须有这一步,或者选择通过参数传递进协程。
// 否则 i 会被 for 所在的协程修改,协程实际使用时值并不确定。
i := i go func() { // 协程结束时报告当前协程执行完毕。
defer func() { wg.Done() }()
fmt.Printf("工作者 %v 启动...rn", i) for task := range taskChan { // 建立匿名函数执行任务的目的是为了捕获单个任务崩溃,防止造成整个工作者、系统崩溃。
func() { defer func() {
err := recover() if err != nil {
fmt.Printf("任务失败:工作者i=%v, task=%v, err=%vrn", i, task, err)
}
}() // 故意崩溃,看看是不是会造成整个系统崩溃。
if task%100==0{ panic("故意崩溃啦")
} // 这里的 task 并不需要通过参数传递进来。
// 原因是这里是同步执行的,并不会被其它协程修改。
fmt.Printf("任务结果=%v ,工作者id=%v, task=%vrn",task*task,i,task)
}()
}
fmt.Printf("工作者 %v 结束。rn", i)
}()
} //等待所有任务完成
wg.Wait() print("全部任务结束")
}
packagemainimport("sync""fmt")
/*
一个标准的协程+信道实现
*/
funcmain(){
taskChan:=make(chanint)
TCount:=10varwgsync.WaitGroup//创建一个sync.WaitGroup // 产生任务gofunc(){
fori:=0;i<1000;i++{
taskChan<-i
}// 全部任务都输入后关闭信道,告诉工作者进程没有新任务了。close(taskChan)
}()
// 启动 TCount 个协程执行任务wg.Add(TCount)
fori:=0;i<TCount;i++{
// 注意:如果协程内使用了 i,必须有这一步,或者选择通过参数传递进协程。// 否则 i 会被 for 所在的协程修改,协程实际使用时值并不确定。i:=i
gofunc(){
// 协程结束时报告当前协程执行完毕。deferfunc(){wg.Done()}()
fmt.Printf("工作者 %v 启动...rn",i)
fortask:=rangetaskChan{
// 建立匿名函数执行任务的目的是为了捕获单个任务崩溃,防止造成整个工作者、系统崩溃。func(){
deferfunc(){
err:=recover()
iferr!=nil{
fmt.Printf("任务失败:工作者i=%v, task=%v, err=%vrn",i,task,err)
}
}()
// 故意崩溃,看看是不是会造成整个系统崩溃。iftask%100==0{panic("故意崩溃啦")
}
// 这里的 task 并不需要通过参数传递进来。// 原因是这里是同步执行的,并不会被其它协程修改。fmt.Printf("任务结果=%v ,工作者id=%v, task=%vrn",task*task,i,task)
}()
}
fmt.Printf("工作者 %v 结束。rn",i)
}()
}
//等待所有任务完成wg.Wait()print("全部任务结束")
}
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android开发之图片旋转功能实现方法【基于Matrix】
- Android编程简单实现拨号器功能的方法
- win10 + Ubuntu20.04 LTS双系统引导界面美化
- Android开发从相册中选取照片的示例代码
- 详解Android WebView的input上传照片的兼容问题
- Ubuntu14.04安装、配置与卸载QT5的步骤详解
- CentOS 8 安装 MariaDB的详细教程
- Android中RecyclerView拖拽、侧删功能的实现代码
- Android单个RecyclerView实现列表嵌套的效果
- Android如何禁止向EditText控件中输入内容详解
- 小程序视角下同构方案思考
- Android基于自带的DownloadManager实现下载功能示例
- Linux服务器搭建nvidia-docker环境过程详解
- Android开发中libs和jinLibs文件夹的作用详解
- Android多线程之同步锁的使用