【问题标题】:Why does net/rpc/client's Go method require a buffered channel?为什么 net/rpc/client 的 Go 方法需要缓冲通道?
【发布时间】:2020-11-26 16:31:09
【问题描述】:

我无法弄清楚为什么该方法需要您专门提供缓冲通道。

来自documentation

func (*Client) Go

func (client *Client) Go(serviceMethod string, args interface{}, reply interface{}, done chan *Call) *Call

Go 异步调用函数。它返回调用结构 代表调用。完成通道将发出信号,当 通过返回相同的 Call 对象来完成调用。如果 done 为零,Go 将分配一个新的频道。 如果非零,done 必须被缓冲或 Go 会故意崩溃。

【问题讨论】:

  • 不是一个完整的答案:the code 中有进一步的评论说“如果调用者通过 done != nil,它必须安排 done 有足够的缓冲区来容纳将要进行的同时 RPC 的数量使用那个通道。如果通道完全没有缓冲,最好不要运行。"
  • 谢谢,我查看了代码,但我很好奇为什么会这样。

标签: go rpc channel


【解决方案1】:

LeGEC 在他们的评论中提到了这一点。

进一步挖掘,你会在 client.go 中找到这一点

func (call *Call) done() {
    select {
    case call.Done <- call:
        // ok
    default:
        // We don't want to block here. It is the caller's responsibility to make
        // sure the channel has enough buffer space. See comment in Go().
        if debugLog {
            log.Println("rpc: discarding Call reply due to insufficient Done chan capacity")
        }
    }
}

从您在这里可以看到,库希望调用是完全异步的。这意味着 done 通道必须有足够的容量来完全解耦两个进程(即完全没有阻塞)。

进一步,当使用 select 语句时,它是执行非阻塞通道操作的惯用方式。

【讨论】:

    猜你喜欢
    • 2019-01-02
    • 2018-04-15
    • 1970-01-01
    • 1970-01-01
    • 2018-10-02
    • 2017-09-06
    • 2019-01-07
    • 2021-12-25
    • 1970-01-01
    相关资源
    最近更新 更多