玩转 Go 语言并发编程:Goroutine 实战指南

一、goroutine 池

  • 本质上是生产者消费者模型
  • 在工作中我们通常会使用可以指定启动的 goroutine 数量-worker pool 模式,控制 goroutine 的数量,防止 goroutine 泄漏和暴涨
  • 一个简易的 work pool 示例代码如下:
package mainimport ("fmt""time"
)func worker (id int, jobs <-chan int, results chan <- int) {//消费者消费任务for j := range jobs {fmt.Printf("worker:%d start job:%d\n", id, j)time.Sleep(time.Second)fmt.Printf("worker:%d end job:%d\n", id, j)results <- j * 2}}func main() {jobs := make(chan int, 100)results := make(chan int, 100)// 1)开启3个goroutine,作为消费者消费 jobs中任务for w := 1; w <= 3; w++ {go worker(w, jobs, results)}// 2)5个任务(生产者生产任务)for j := 1; j <= 5; j++ {jobs <- j}close(jobs)// 3)输出结果for a := 1; a <= 5; a++ {v := <-resultsfmt.Println(v)}
}

二、打印奇数偶数

1、一个无缓冲管道实现
  • 首先我们这里通过 make(chan int),开辟的通道是一种无缓冲通道
  • 所以当对这个缓冲通道写的时候,会一直阻塞等到某个协程对这个缓冲通道读
  • 而这里我讲 ch <- true 理解为色号给你吃,它却是需要等到某个协程读了才能继续运行
package mainimport ("fmt""sync"
)var wg sync.WaitGroupfunc printJS(ch chan bool) {defer wg.Done()for i := 1; i <= 9; i += 2 {fmt.Println("js", i)   // 奇数先打印ch <- true         // 给偶数打印函数一个信号(需要等到某个协程读了再能继续运行)<-ch}
}func printOS(ch chan bool) {defer wg.Done()for i := 2; i <= 10; i += 2 {<-ch  // 偶数等待奇数函数 向chan发送信号fmt.Println("os", i)ch <- false         // 给奇数打印函数一个信号(需要等到某个协程读了再能继续运行)}
}func main() {// 新建一个无缓冲管道(无缓冲管道只能一个协程写入,然后另外一个协程来读取)ch := make(chan bool)wg.Add(2)go printJS(ch)go printOS(ch)wg.Wait()
}
2、两个无缓冲管道实现
package mainimport ("fmt""sync"
)var ch1 = make(chan bool)
var ch2 = make(chan bool)
var wg sync.WaitGroupfunc go1JS() {defer wg.Done()for i := 1; i <= 10; i += 2 {<-ch1 // ch1获取数据成功就不阻塞,进行下一步fmt.Println(i)ch2 <- true // 向ch2发送信号,打印奇数}<-ch1  // 因为main函数最初向ch1放入了一个数据,所以最后打印结束后取出,否则死锁
}
func go2OS() {defer wg.Done()for i := 2; i <= 10; i += 2 {<-ch2fmt.Println(i)ch1 <- true}
}
func main() {wg.Add(2)go go1JS()  // 打印奇数go go2OS()  // 打印偶数ch1 <- true // 先让奇数的协程执行wg.Wait()
}

三、超时控制

1、基础版
package mainimport ("fmt""math/rand""time"
)// 在 main 函数里调用给定的 rpc 方法,并设置超时时间为 10 秒
// 在等待过程中如果超时则取消等待并打印 "timeout" ,如果没有超时则打印出 rpc 的返回结果。
// rpc 方法不可以修改
func main() {ch := make(chan bool)var ret intgo func() {ret = rpc()<-ch}()count := 0for count < 10 {if ret != 0 {fmt.Println(ret)break}time.Sleep(time.Second)count += 1}if count >= 10 {ch <- falsefmt.Println("timeout")}
}// 这是你要调用的方法,可以看作一个黑盒
// 它的耗时是 1~15 秒内的随机数
// 最终返回一个随机的 int 类型
func rpc() int {cost := rand.Intn(15) + 1fmt.Printf("rpc will cost %d seconds\n", cost)time.Sleep(time.Duration(cost) * time.Second)return cost
}func init() {rand.Seed(time.Now().UnixNano())
}
2、time.After控制超时
package mainimport ("fmt""time"
)func main() {workDoneCh := make(chan bool, 1)go func() {LongTimeWork()     //这是我们要控制超时的函数workDoneCh <- true // 函数正常执行结束给 chan信号正常退出}()select {case <-workDoneCh: // 当协程执行完成后会向这个 channel 发送一个数据,收到即可结束fmt.Println("Success!")case <-time.After(3 * time.Second): //timeout到来fmt.Println("timeout") // 3s无返回超时退出}
}func LongTimeWork() {time.Sleep(time.Second * 2)
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/215889.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小程序跳转tabbar,tabbar页面不刷新

文章地址&#xff1a;12.小程序 之切换到tabBar页面不刷新问题_360问答 解决办法备份&#xff1a; wx.switchTab&#xff1a;跳转到 tabBar 页面&#xff0c;并关闭其他所有非 tabBar 页面 wx.reLaunch&#xff1a;关闭所有页面&#xff0c;打开到应用内的某个页面。 wx.reLa…

解决微信小程序中 ‘nbsp;‘ 空格不生效的问题

在微信小程序开发中&#xff0c;我们经常会使用 来表示一个空格。这是因为在 HTML 中&#xff0c;空格会被解析为一个普通字符&#xff0c;而不会产生实际的空白间距。而 是一种特殊的字符实体&#xff0c;它被解析为一个不可见的空格&#xff0c;可以在页面上产生真正的空…

力扣70. 爬楼梯

动态规划 思路&#xff1a; 使用递归比较容易理解&#xff0c; f(n) f(n - 1) f(n - 2)&#xff1b; 到剩余1级台阶有 f(n - 1)&#xff0c;到剩余2级台阶有 f(n-2)&#xff1b;边界情况是 n 0, f(0) 1n 1, f(1) 1n 2, f(2) 2 递归代码实现&#xff1a; class Soluti…

Axure RP 9 入门教程

1. Axure简介 Axure 是一个交互式原型设计工具&#xff0c;可以帮助用户创建复杂的交互式应用程序和网站。Axure 能够让用户快速构建出具有高度可交互性的原型&#xff0c;可以在团队中进行协作、分享和测试。 使用 Axure 可以设计出各种不同类型的原型&#xff0c;包括网站、移…

系列十五、搭建redis集群

一、概述 上篇文章介绍了redis集群的相关知识&#xff0c;本章实战演示redis的集群环境的详细搭建步骤。如果帮助到了你&#xff0c;请点赞 收藏 关注&#xff01;有疑问的话也可以评论区交流。 二、搭建步骤 2.1、预备知识 判断一个集群中的节点是否可用&#xff0c;是集群…

【SpringBoot篇】详解基于Redis实现短信登录的操作

文章目录 &#x1f970;前言&#x1f6f8;StringRedisTemplate&#x1f339;使用StringRedisTemplate⭐常用的方法 &#x1f6f8;为什么我们要使用Redis代替Session进行登录操作&#x1f386;具体使用✨编写拦截器✨配置拦截器&#x1f33a;基于Redis实现发送手机验证码操作&am…

EarCMS 前台任意文件上传漏洞复现

0x01 产品简介 EarCMS是一个APP内测分发系统的平台。 0x02 漏洞概述 EarCMS前台put_upload.php中,存在pw参数硬编码问题,同时sql语句pdo使用错误,没有有效过滤sql语句,可以控制文件名和后缀,导致可以任意文件上传。 0x03 复现环境 FOFA:app="EearCMS" 0x0…

Flutter实现自定义二级列表

在Flutter开发中&#xff0c;其实系统已经给我们提供了一个可靠的二级列表展开的API&#xff08;ExpansionPanelList&#xff09;&#xff0c;我们先看系统的二级列表展开效果&#xff0c;一次只能展开一个&#xff0c;用ExpansionPanelList.radio实现 由此可见&#xff0c;已经…

容器化升级对服务有哪些影响?

容器技术是近几年计算机领域的热门技术&#xff0c;特别是随着各种云服务的发展&#xff0c;越来越多的服务运行在以 Docker 为代表的容器之内。 本文我们就来分享一下容器化技术相关的知识。 容器化技术简介 相比传统虚拟化技术&#xff0c;容器技术是一种更加轻量级的操作…

分治法求最大子列和

给定N个整数的序列{ A1, A2, …, AN}&#xff0c;其中可能有正数也可能有负数&#xff0c;找出其中连续的一个子数列&#xff08;不允许空序列&#xff09;&#xff0c;使它们的和尽可能大&#xff0c;如果是负数&#xff0c;则返回0。使用下列函数&#xff0c;完成分治法求最大…

CorelDRAW软件2024版本好用吗?有哪些功能优势

CorelDRAW是一款综合性强大的专业平面设计软件&#xff0c;其功能覆盖了矢量图形设计、高级文字编辑、精细绘图以及多页文档和页面设计。该软件不仅适用于广告设计、包装设计&#xff0c;还广泛应用于出版、网页设计和多媒体制作等多个领域。下面就给大家介绍一下CorelDRAW这款…

0012Java安卓程序设计-ssm记账app

文章目录 **摘要**目 录系统设计5.1 APP端&#xff08;用户功能&#xff09;5.2后端管理员功能模块开发环境 编程技术交流、源码分享、模板分享、网课分享 企鹅&#x1f427;裙&#xff1a;776871563 摘要 网络的广泛应用给生活带来了十分的便利。所以把记账管理与现在网络相…

arkts编译报错-arkts-limited-stdlib错误【Bug已完美解决-鸿蒙开发】

文章目录 项目场景:问题描述原因分析:解决方案:适配指导案例此Bug解决方案总结项目场景: arkts编译报错-arkts-limited-stdlib错误。 我用Deveco studio4.0 beta2开发应用,报arkts-limited-stdlib错误 报错内容为: ERROR: ArKTS:ERROR File: D:/prRevivw/3792lapplica…

[Verilog]用Verilog实现串并转换/并串装换

用Verilog实现串并转换/并串装换 摘要 一、串并转换模块 串转并就是将低3位信号和输入信号一起赋值。因为经过转换后&#xff0c;码元速率会将为原来四分之一&#xff0c;所以设置4分频时钟&#xff0c;将其输出。而并转串就是不断右移&#xff0c;取高位输出。 module serial…

Android 11.0 systemui锁屏页面时钟显示样式的定制功能实现

1.前言 在11.0的系统ROM定制化开发中,在进行systemui的相关开发中,当开机完成后在锁屏页面就会显示时间日期的功能,由于 开发产品的需求要求时间显示周几上午下午接下来就需要对锁屏显示时间日期的相关布局进行分析,然后实现相关功能 效果图如图: 2.systemui锁屏页面时钟显…

mysql原理--B+树索引

1.没有索引的查找 1.1.在一个页中的查找 (1). 以主键为搜索条件 可以在 页目录 中使用二分法快速定位到对应的槽&#xff0c;然后再遍历该槽对应分组中的记录即可快速找到指定的记录。 (2). 以其他列作为搜索条件 这种情况下只能从 最小记录 开始依次遍历单链表中的每条记录&am…

值得收藏的练习打字网站

本文对一些好用的练习打字的网站进行了汇总整理&#xff0c;方便大家使用 一&#xff1a;程序猿练习打字&#xff1a; 1.Typing Practice for Programmers http://Typing.io 是程序员的打字导师。它的练习课程基于开源代码&#xff0c;让你在不断的练习中提升自己的码字速度…

Python:核心知识点整理大全15-笔记

目录 ​编辑 7.3.2 删除包含特定值的所有列表元素 pets.py 7.3.3 使用用户输入来填充字典 mountain_poll.py 7.4 小结 第8章 函 数 8.1 定义函数 greeter.py 8.1.1 向函数传递信息 8.1.2 实参和形参 8.2.1 位置实参 2. 位置实参的顺序很重要 8.2.2 关键字实参 往…

Ansible通过kubernetes.core.k8s_info和kubernetes.core.k8s访问OCP

文章目录 环境OCPClient&#xff08;Ansible控制节点&#xff09; 步骤准备工作在client端配置ssh免密登录OCP端在client端安装Ansible kubernetes.core.k8s_info第1次尝试在OCP端安装python和pip3在OCP端安装kubernetes在OCP端安装PyYAML第2次尝试在OCP端配置config文件第3次尝…

计算机循环神经网络(RNN)

计算机循环神经网络&#xff08;RNN&#xff09; 一、引言 循环神经网络&#xff08;RNN&#xff09;是一种常见的深度学习模型&#xff0c;适用于处理序列数据&#xff0c;如文本、语音、时间序列等。RNN通过捕捉序列数据中的时间依赖关系和上下文信息&#xff0c;能够解决很…