猿问

有没有可靠的方法来确保 Go 通道在读取时不会阻塞?

这是对上一个具有相似名称的线程的后续操作。


它有一个公认的答案,但该答案并不能真正回答问题。从那个线程,这里是用例:


if len(myChannel) > 0 {

   // Possible issue here: length could have changed to 0 making this blocking

   elm := <- myChannel

   return elm

 }

OP 称其为“可能的问题”,但它是一个确定的问题:一种竞争条件,其中另一个消费者可能从 if 条件的评估和两个语句的执行之间的通道中提取了一个值。


现在,我们被告知 Go Way 更倾向于通道而不是互斥锁,但在这里,如果不将互斥锁和通道配对在一起,并使用我们新的并发数据类型而不是通道。


可以吗?真的没有办法通过提前检查空间来可靠地确保 recv 不会阻塞吗?(与 Java 中的 BlockingQueue.poll() 或其他基于队列的消息传递 IPC 设施中的类似设施相比...)


摇曳的蔷薇
浏览 195回答 2
2回答

ibeautiful

Rob Napier 的回答是正确的。但是,您可能过于努力地实现非阻塞行为,假设它是一种反模式。使用 Go,您不必担心阻塞。继续,无罪地阻止。它可以使代码更容易编写,尤其是在处理 i/o 时。CSP 允许您设计数据驱动的并发程序,这些程序可以很好地扩展(因为不会过多地使用互斥锁)。通过通道进行通信的一小组 goroutine 可以表现得像一个更大系统的组件;这些组件(也通过通道进行通信)可以组合成更大的组件;这种模式以越来越大的比例重复。传统上,人们从顺序代码开始,然后尝试通过添加 goroutine、通道、互斥体等来添加并发。 作为练习,尝试不同的东西:尝试设计一个最大并发的系统- 尽可能深入地使用 goroutine 和通道。您可能对您实现的性能不满意……所以也许可以尝试考虑如何通过组合(而不是划分)块来改进它,减少 goroutine 的总数,从而实现更优化的并发性。

慕丝7291255

这正是默认情况下select的用途:var elm myTypeselect {case elm = <-myChannel:default:}return elmelm如果可以,则进行分配,否则返回零值。有关更广泛的示例,请参阅Effective Go中的“泄漏缓冲区” 。
随时随地看视频慕课网APP

相关分类

Go
我要回答