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

Bad*_*Zen 0 concurrency multithreading go

这是具有类似名称的先前线程的后续跟进.

它有一个公认的答案,但答案并没有真正回答这个问题.从该线程,这是用例:

if len(myChannel) > 0 {
   // Possible issue here: length could have changed to 0 making this blocking
   elm := <- myChannel
   return elm
 }
Run Code Online (Sandbox Code Playgroud)

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

现在,我们被告知Go Way是支持频道而不是互斥,但是在这里我们似乎无法实现基本的非阻塞读取(通过轮询长度和原子读取)而无需将互斥锁和通道配对在一起,并使用我们的新并发数据类型而不是通道.

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

Rob*_*ier 9

这正是默认情况select:

var elm myType
select {
case elm = <-myChannel:
default:
}
return elm
Run Code Online (Sandbox Code Playgroud)

elm如果可以,则指定,否则返回零值.有关更广泛的示例,请参阅Effective Go的 "泄漏缓冲区" .