golang中是否可以接受优雅的close-write并发模式?

时间:2015-09-18 21:01:34

标签: go concurrency

我刚刚开始使用并发。我有其他语言的并发经验,如果你想写一个封闭的频道,我会感到非常难过。

这种模式非常有用,因为你可以解耦actor的生命周期并使它们独立。这使您无需同步清理它们。基本上我可以让读者在关闭之前关闭通道,并通知任意数量的写入器并通过通道上的写入错误停止阻塞(取消)。

因此,我编写了一个通用函数来处理这种形式的消息传递:

/// Sends a message to a remote general channel.
/// Returns true if the message was sent (the send stopped blocking) or false if
/// the sender closed the channel.
/// When the channel is unbuffered, this function returning true means that the
/// sender has received the message and is acting on it.
func SendRemoteCmd(ch chan interface{}, msg interface{}) bool {
    defer func() {
        recover()
    }()
    ch <- msg
    return true
}

效果很好,我只是害怕golang开发者会生气,打电话给我,告诉我他们在阅读这段代码时会“找到我”。也许有一些很好的理由说明语言之神首先决定这应该是恐慌。如果是这种情况,你建议用什么设计?

1 个答案:

答案 0 :(得分:2)

由于发送到关闭频道是一个程序错误,您的频道发送到可以关闭的频道必须同步。一般来说,正确的模式是在尝试发送之前获得某种锁定,如果该频道可以被第三方关闭。

在您尝试发送可以关闭的频道之前,这并不是特别有趣,因为select语句的一部分涉及其他可能的操作。在这种情况下,一个常见的模式是将频道设置为nil,如果对它们的操作不应该,或者不能进行。我在torrent客户端hereconnection.writeOptimizer函数中有一个非常复杂的例子。

请注意,示例中仔细考虑了写入管道中涉及的资源的所有权,这是一种防止问题的好方法,例如关闭渠道。 writeOptimizer有效地拥有connection.writeCh,并通过关闭它向下游发出信号,表示没有其他数据到来。它也是发送到该例程的唯一goroutine,从而避免了必须通过其他方式将写入与通道关闭同步。