golang中for循环遍历channel时需要注意的问题详解
作者:xialeistudio 发布时间:2024-04-29 13:05:16
标签:golang,for循环,channel
前言
for循环是Go语言唯一的循环结构,最近在做一个基于RabbitMQ的应用,由于官方的qos没有golang的版本,所以出了一点问题。
问题代码如下:
_, ch, err := component.NewRabbitMQ()
if err != nil {
panic(err)
}
if err := ch.Qos(10, 0, true); err != nil {
panic(err)
}
msgs, err := ch.Consume("push", "", false, false, false, false, nil)
if err != nil {
panic(err)
}
for m := range msgs {
go func(d *amqp.Delivery) {
defer func() { d.Ack(false) }
// 处理消息
}(&m)
}
发现消费到10条消息,进程就退出了,但是exit code为0,表示系统是正常退出,由于做了日志记录可以确定消费了10条,所以初步确定是qos相关问题。
排查过程
首先是把d的tag打印出来,发现全部是一样的,可以确定是重复的一条消息
一开始想到可能是经典的go协程执行在for循环结束以后导致的,但是看我的代码不属于这种情况,有使用&m保证每一条消息都是不同循环传入的。所以判断可能是for循环的传递问题。
确定方向之后开始写了一个测试项目用来验证我的想法是否正确。
测试代码
package main
import "fmt"
func main() {
ch := make(chan int, 10)
for i := 0; i < 10; i++ {
ch <- i
}
close(ch)
for v := range ch {
fmt.Println(&v)
}
}
执行输出
0xc420086008
0xc420086008
0xc420086008
0xc420086008
0xc420086008
0xc420086008
0xc420086008
0xc420086008
0xc420086008
0xc420086008
到这里才焕然大悟,for循环中,如果循环变量不是指针,那么每次的变量是同一个,不过值变了。,所以上例中的RabbitMQ go协程消费消息那里,需要直接传递值而不是指针,经过测试之后发现,问题确实解决了。
题外话
测试代码那里,如果不close掉channel是会发生死锁的,原因是 当for循环读完channel的10个值之后会继续尝试读取下一个,而由于channel为空又没关闭,会一直阻塞形成死锁
TOOD
研究RabbitMQ Consumer部分的源码来看看消费channel被关闭的问题。
来源:https://www.ddhigh.com/2018/04/05/golang-for-over-channels.html


猜你喜欢
- 在前面的文章 Python 计算机视觉(十五)—— 图像特效处理 中我已经介绍了大部分的图像的特效处理,但还是忽略了油画特效的处理,在本篇文
- Web,全称为 World Wide Web,是 Internet 上最重要和最为人们所熟知的应用之一。Web 是指 Internet 上所
- 设计是一个输入-输出的过程,因为首先有用户的需求,客户的项目才有设计的产生,设计是带有目的性和市场行为的,当然也有一部分的创造性设计,仅仅为
- 本文实例讲述了js控制多图左右滚动切换效果。分享给大家供大家参考。具体如下:这是一款纯js实现点击左右按钮图片自动左右平滑滚动,默认5个一组
- 请问css如何实现一张图片的倒影。出来的效果就像这样:下面是使用了滤镜来实现倒影的效果:<div style=" width
- 🌟 写在前面专栏介绍:凉哥作为 Vue 的忠实 粉丝输出过大量的 Vue 文章,应粉丝要求开始更新 Vue3 的相关技术文章,Vue 框架目
- 几乎是一夜之间,微信小游戏《羊了个羊》火了。?这个依靠寻找相同元素消除方块的小游戏,凭借其“变态级别&rdquo
- Sun周三宣布,准备以10亿美元收购MySQL开源数据库公司。据悉,Sun将支付大约8亿美元现金给MySQL,以获得其私募股票,另外,Sun
- GetRepeatTimes(TheChar,TheString) 得到一个字符串在另一个字符串当中出现几次的函数(新)如:response
- 使用Python创建websocket服务端,并给出不同客户端的请求一、 WebSocket是啥WebSocket 和HTTP一样,也是一种
- 在利用python进行flask等开发过程中经常需要配置虚拟环境以方便针对不同的项目需求配置不同的生产环境。在python3.3之前,需要利
- 一、前言Python logging 模块定义了为应用程序和库实现灵活的事件日志记录的函数和类。程序开发过程中,很多程序都有记录日志的需求,
- 以前用js很少用到js的正则表达式,即使用到了,也是诸如邮件名称之类的判断,网上代码很多,很少有研究,拿来即用。最近开发遇到一些需要使用正则
- 内容摘要:Cookies的值比ASP其他集合(例如Form和ServerVariables)的值要复杂得多。Cookie是一小块由浏览器存贮
- 用户日活百万级,注册用户千万级,而且若还没有进行分库分表,则该DB里的用户表可能就一张,单表上千万的用户数据。某系统专门通过各种条件筛选大量
- 所谓产品其实最终展现在用户面前的只是界面而已,所谓界面绝大多数时候只包括两个部分:图片、文字。重视界面上的每一个像素和每一个文字是UED的基
- 在ASP中使用FSO组件生成HTML静态页面,共有两个页面index.htm是首页.程序比较简单,主要是用了ASP里的文件操作
- wp_mail() 函数用来发送邮件,类似于 PHP 的 mail() 函数。默认的发件人名称是 WordPress,发件人邮箱是类似 wo
- 背景使用python进行图像可视化,很多情况下都需要subplots将多幅图像绘制在一个figure中。因为使用频率足够高,那么程序员就需要
- 我有一个朋友,一直纠结一个问题:arguments接受的实参是一个列表,得到的是一个像数组一样的东西,于是他想实现无限参数求和,在遍历数组求