猿问

goroutine使用了外面的变量,造成闭包问题。怎么解决呢?

问题描述
我有这样一个程序,他从一个items列表中读取items,然后,打印一下这个item,交个一个channel
//从out队列接收数据
for_,item:=rangeresult.Items{
fmt.Println("gotitem:",item)
gofunc(){
c.ItemChan<-item
}()
}
在另一个地方,起了一个goroutine,来接收
gofunc(){
count:=0
for{
item:=<-out
count++
fmt.Printf("获取到的item:%d,当前saver计数count是:%d\n",item,count)
}
}()
很简单的一个东西,但是发现。写入是打印的item没有重复,但读取的channel,打印有重复。最后发现应该是写入是,channel阻塞,而外层循环还在继续,导致item更新了,然后在写入channel的已经是几个相同的item了
问题出现的环境背景及自己尝试过哪些方法
我尝试给写入添加sleep,这样只要确保这个被消费了,然后在写入,就没问题
for_,item:=rangeresult.Items{
time.Sleep(time.Millisecond*100)
fmt.Println("gotitem:",item)
gofunc(){
c.ItemChan<-item
}()
}
但显然,这个不符合需求。
那么,我的问题是,我有一个列表要不断读取,通过goroutine塞到一个channel里面,但这样会造成闭包问题,该怎么解决呢?
也许,将写入改成一个大的goroutine是个好办法?goroutine包裹整个for循环,然后,此时在写入channel就是阻塞的了
相关代码
//请把代码文本粘贴到下方(请勿用图片代替代码)
你期待的结果是什么?实际看到的错误信息又是什么?
RISEBY
浏览 555回答 2
2回答

慕田峪4524236

自己思考了一下。其实,既然是闭包。那么,只要将item作为参数,传递给这个循环goroutine,就可以了他作为形参,自然不会被修改//从out队列接收数据for_,item:=rangeresult.Items{fmt.Println("gotitem:",item)gofunc(recinterface{}){c.ItemChan

叮当猫咪

你打印写入的地方有问题。for_,item:=rangeresult.Items{//fmt.Println("gotitem:",item)//把这个放gofunc()里面gofunc(){fmt.Println("gotitem:",item)c.ItemChan
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答