【问题标题】:Go non-blocking channel send, test-for-failure before attempting to send?在尝试发送之前进行非阻塞通道发送,测试失败?
【发布时间】:2015-05-14 23:36:50
【问题描述】:

有没有一种方法可以在不实际尝试发送的情况下测试 go 通道发送失败?标准的非阻塞发送是这样的:

msg := "hi"
select {
    case messages <- msg:
        fmt.Println("sent message", msg)
    default:
        fmt.Println("no message sent")
    }

问题是我需要准备好发送“msg”才能测试频道。

我想测试一下发送是否会以不需要“msg”准备发送的方式失败。

【问题讨论】:

  • 发送将被缓冲、阻塞、超时或完成。就像 JimB 所说:假设您不会被阻止是一场数据竞赛。如果您不认为发送方处于正确的发送状态或接收方处于正确的接收状态,那么这只是协议设计的问题。您可以从客户端获取有关它是否认为自己会接受发送的状态更新。
  • 所以答案是“否”。没有内置机制可以做到这一点。感谢您的验证。
  • 需要注意的是,如果你使缓冲区足够大,并且设法永远不会填满缓冲区,那么在实践中你将永远不会遇到阻塞。从不填充缓冲区要求消息总是被及时消费;仅当发送方在缓冲区已满之前停止发送时,才能保证这一点。仔细想想,这有点像发送方“阻塞”(拒绝发送),因为它知道接收方已满。

标签: go nonblocking channels


【解决方案1】:

这在一般情况下不会有任何好处,因为这样你就有了比赛。生成消息后,通道可能不再准备好发送。

如果你需要这种模式,你要么需要第二个信号通道,

select {
    case <-ready:
        msg := generateMsg()
        messages <- msg
        fmt.Println("sent message", msg)
    default:
        fmt.Println("no message sent")
}

或者您可以使用sync.Cond

【讨论】:

    猜你喜欢
    • 2017-04-21
    • 2017-02-09
    • 1970-01-01
    • 1970-01-01
    • 2013-05-03
    • 2012-08-24
    • 2011-05-25
    • 1970-01-01
    • 2018-01-06
    相关资源
    最近更新 更多