问题出在标题中。让我们说我有几个goroutines(超过100个),所有这些都最终将数据发送到一个chan(将其命名为mychan := make(chan int)
)另一个goroutine在无尽的for循环中<- mychan
是否可以或者陈可能会丢失一些数据?我应该使用缓冲的陈吗?或者也许我要创建一个陈和一个恶魔&#34; goroutine会为每个工作者goroutine提取消息吗?
答案 0 :(得分:2)
如果某些内容已经成功发送到频道中,那么它就无法在正常工作的环境中丢失(我的意思是,如果你篡改了你的记忆,或者你因为宇宙射线而有点翻转当然不要指望任何事情。)
ch <- x
返回时成功发送消息。否则,如果它发生恐慌,它就不会真正被发送,如果你没有恢复,你可能会声称它已经丢失(但是,它会因应用程序逻辑而丢失)。如果频道关闭,或者说你的内存不足,可能会发生恐慌。
同样,如果发件人以非阻止模式(通过使用select)进入频道,您的频道中应该有足够的缓冲区,因为邮件可能会丢失&#34; (虽然有点故意)。例如,signal.Notify
正在以这种方式工作:
封装信号不会阻止发送到c:调用者必须确保c有足够的缓冲空间来跟上预期的信号速率。
答案 1 :(得分:1)
不,他们不能迷路。
虽然语言规范不以任何方式对通道强加任何特定实现,但您可以将它们视为保护单个值(对于单个消息)或它们的数组/列表(对于缓冲)的关键部分或互斥体信道)。
然后以这样的方式强制执行语义,即只要goroutine想要向频道发送消息,它就会进入该关键部分/锁定互斥锁,然后在发送时成功获取&#39; sa当没有消息时,它的消息或块的插槽。一旦出现这样的插槽 - 有人收到了现有消息 - 发送成功并且发送goroutine被解除阻塞。
这是一个简化的解释,但我希望它能为您提供正确的想法。换句话说,Go中的频道与消息队列不同,消息队列通常对丢失消息感到满意。
另一方面,我不确定如果接收器在某个特定状态下发生接收消息时会发生什么事。 IOW我不确定Go是否保证在接收器出现恐慌的情况下发送或不发送消息。
哦,还有那个主要goroutine的灰色区域退出(那个运行main.main()
函数的那个):规范状态明显比主要goroutine不等待任何其他goroutine完成时它退出了。因此,除非你以某种方式安排所有衍生的goroutine的同步控制关闭,否则我相信它们可能会丢失消息。另一方面,在这种情况下,无论如何世界正在崩溃......
答案 2 :(得分:0)
消息不会丢失。它可以不发送。没有定义goroutines执行的命令。所以你的无限循环只能从一个工人那里一次接收,如果它不在主线程中,甚至可以睡觉。为了确保您的队列以常规方式工作,您最好明确地在“主要”接收每个工作人员的消息。