我有一部分频道都收到相同的消息:func broadcast(c <-chan string, chans []chan<- string) { for msg := range c { for _, ch := range chans { ch <- msg } }}但是,由于每个通道chans都可能以不同的速率被读取,因此当我遇到慢消费者时,我不想阻止其他通道。我已经用 goroutines 解决了这个问题:func broadcast(c <-chan string, chans []chan<- string) { for msg := range c { for _, ch := range chans { go func() { ch <- msg }() } }}但是,传递到每个通道的消息的顺序很重要。我查看了规范以查看通道在阻塞时是否保持顺序,我发现的是:如果容量大于零,则通道是异步的:如果缓冲区未满(发送)或非空(接收),则通信操作成功而不会阻塞,并且元素按发送顺序接收。对我来说,如果写入被阻塞,那么它不是“发送”,而是等待发送。有了这个假设,当多个 goroutines 在写入时被阻塞时,上面没有说明发送的顺序。通道解除阻塞后,是否有任何关于发送顺序的保证?
3 回答
肥皂起泡泡
TA贡献1829条经验 获得超6个赞
在此代码中,没有任何保证。
给定示例代码的主要问题不在于通道行为,而在于创建的众多 goroutine。所有的 goroutine 都在同一个叠片循环中“触发”而无需进一步同步,因此即使在它们开始发送消息之前,我们也不知道哪些将首先执行。
然而,这通常会引发一个合理的问题:如果我们以某种方式保证几个阻塞发送指令的顺序,我们是否保证以相同的顺序接收它们?
发送的“发生在之前”属性很难创建。我担心这是不可能的,因为:
在发送指令之前任何事情都可能发生:例如,其他 goroutine 是否执行自己的发送
在发送中被阻塞的 goroutine 不能同时管理其他类型的同步
例如,如果我有 10 个编号为 1 到 10 的 goroutine,我无法让它们以正确的顺序同时将自己的编号发送到通道。我所能做的就是使用各种顺序技巧,例如在 1 个单独的 goroutine 中进行排序。
aluckdog
TA贡献1847条经验 获得超7个赞
不,没有任何保证。
即使通道未满,如果两个 goroutine 大约在同一时间启动并发送给它,我认为无法保证首先启动的 goroutine 会真正先执行。所以你不能指望消息按顺序到达。
- 3 回答
- 0 关注
- 292 浏览
添加回答
举报
0/150
提交
取消