为了账号安全,请及时绑定邮箱和手机立即绑定

发送到频道的消息会丢失吗?

发送到频道的消息会丢失吗?

Go
青春有我 2021-11-29 19:22:16
问题在标题中。假设我有几个 goroutine(超过 100 个),所有这些 goroutine 最终都会将数据发送给一个 chan(命名mychan := make(chan int)) 另一个 goroutine<- mychan在无限循环中执行 是否可以,或者 chan 可能会丢失一些数据?我应该使用缓冲的 chan 吗?或者,也许我要创建一个 chan 和一个“恶魔” goroutine 来为每个工作 goroutine 提取消息?
查看完整描述

3 回答

?
ITMISS

TA贡献1871条经验 获得超8个赞

如果某些东西已成功发送到通道中,那么不会,它不会在正常工作的环境中丢失(我的意思是,如果您篡改了您的记忆或由于宇宙射线而导致位翻转,那么当然不要指望任何东西)。

ch <- x返回时消息发送成功。否则,如果它发生恐慌,它并没有真正被发送,如果你没有恢复,你可能会声称它丢失了(但是,由于应用程序逻辑,它会丢失)。如果通道已关闭,或者您的内存不足,则可能会发生恐慌。

类似地,如果发送方以非阻塞模式(通过使用选择)进入通道,则通道中应该有足够的缓冲区,因为消息可能会“丢失”(尽管以某种方式有意)。例如signal.Notify以这种方式工作:

包信号不会阻塞发送到 c:调用者必须确保 c 有足够的缓冲区空间来跟上预期的信号速率


查看完整回答
反对 回复 2021-11-29
?
函数式编程

TA贡献1807条经验 获得超9个赞

不,他们不能丢失。

虽然语言规范不以任何方式强加给渠道任何特定的实现,你可以把它们想象成信号灯保护一个单值(单个消息)或它们的阵列/列表(缓冲渠道)。

然后以这样一种方式强制执行语义,一旦 goroutine 想要向通道发送消息,它就会尝试使用该信号量获取一个空闲的数据槽,然后要么成功发送 - 它的消息就有一个空闲槽- 或阻止 - 当没有时。一旦出现这样的槽——有人收到了现有的消息——发送成功并且发送 goroutine 被解除阻塞。

这是一个简化的解释,但我希望它能让你得到正确的想法。换句话说,Go 中的通道不像通常对丢失消息感到满意的消息队列。

附带说明一下,我不确定如果接收方在即将收到您的消息时在某些特定状态下发生恐慌会发生什么。IOW 我不确定 Go 是否保证在接收者在不幸的时刻惊慌失措的情况下发送或不发送消息。

哦,还有主 goroutine 退出的灰色区域(运行该main.main()函数的那个):规范状态比主 goroutine 退出时不等待任何其他 goroutine 完成更清楚。因此,除非您以某种方式安排所有生成的 goroutine 的同步受控关闭,否则我相信它们可能会丢失消息。另一方面,在这种情况下,无论如何世界都在崩溃……


查看完整回答
反对 回复 2021-11-29
?
胡说叔叔

TA贡献1804条经验 获得超8个赞

消息不能丢失。可以不发送。goroutines 的执行顺序未定义。所以你的无休止的 for 循环只能从一个工人接收,如果它不在主线程中,甚至可以休眠。为了确保您的队列以常规方式工作,您最好在“主要”中明确地为每个工作人员接收消息。


查看完整回答
反对 回复 2021-11-29
  • 3 回答
  • 0 关注
  • 186 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信