3 回答
TA贡献1804条经验 获得超7个赞
这是一个很好的问题 - 它涉及进行并发设计时的一些重要问题。如前所述,根据当前的实现,您的具体问题的答案是基于 FIFO。它不太可能有所不同,除非实施者出于某种原因认为 LIFO 更好。
有没有保证,虽然。因此,您应该避免创建依赖于特定实现的代码。
更广泛的问题涉及非确定性、公平和饥饿。
也许令人惊讶的是,基于 CSP 的系统中的非确定性并非来自并行发生的事情。有可能是因为并发,但不是因为并发。相反,当做出选择时会出现不确定性。在 CSP 的正式代数中,这是用数学建模的。幸运的是,您无需了解数学即可使用 Go。但形式上,两个 goroutine 代码并行执行,如果消除所有选择,结果仍然是确定性的。
Go 允许select
通过 goroutine 之间共享的通道的末端显式和隐式引入非确定性的选择。如果你有点对点(一个读者,一个作者)的渠道,就不会出现第二种。因此,如果它在特定情况下很重要,则您可以做出设计选择。
公平和饥饿通常是同一枚硬币的两面。饥饿是那些可能导致性能不佳,更可能导致错误行为的动态问题之一(以及死锁、活锁和竞争条件)。这些动态问题是不可测试的(更多关于这个),需要一些层次分析来解决。显然,如果系统的一部分因为无法访问某些资源而没有响应,那么在管理这些资源时就需要更加公平。
由于当前的 FIFO 行为,对通道端的共享访问可以很好地提供一定程度的公平性,这似乎就足够了。但是,如果您希望它得到保证(无论实现的不确定性如何),则可以select
在数组中使用 a和一组点对点通道。通过始终按照将最后选择的放在堆底部的顺序优先选择它们,很容易实现公平索引。此解决方案可以保证公平性,但可能会带来很小的性能损失。
(旁白:请参阅“Wot No Chickens”,了解英国坎特伯雷的研究人员关于 Java 虚拟机中的公平性缺陷的一个有点有趣的发现——该缺陷从未得到纠正!)
TA贡献1817条经验 获得超14个赞
顺序未指定,但当前的实现使用 FIFO 队列来等待 goroutine。
权威文档是Go Memory Model。内存模型没有为发送到同一个通道的两个 goroutine 定义发生在之前的关系,因此没有指定顺序。同上接收。
- 3 回答
- 0 关注
- 198 浏览
添加回答
举报