【问题标题】:Aborting a Read() call from another goroutine中止来自另一个 goroutine 的 Read() 调用
【发布时间】:2013-07-28 15:06:37
【问题描述】:

我正在使用 IMAP 服务器,其中一项操作是升级连接以使用 TLS(通过 STARTTLS 命令)。我们当前的架构有一个 goroutine 从套接字读取数据,解析命令,然后通过通道发送逻辑命令。另一个 goroutine 从该通道读取并执行命令。总的来说,这很有效。

但是,当执行STARTTLS 时,我们需要停止当前正在进行的Read() 调用,否则Read() 将消耗来自TLS 握手的字节。我们可以在两者之间插入另一个类,但随后该类将在 Read() 调用中被阻止,并且我们遇到了同样的问题。如果网络连接是一个通道,我们可以添加另一个信号通道并使用 select{} 块来停止读取,但网络连接不是通道(只需将其包装在一个 goroutine 中,通道只是将问题转移到该 goroutine) .

有什么方法可以在 Read() 呼叫开始后停止它,而无需等待超时或类似的东西?

【问题讨论】:

    标签: io go


    【解决方案1】:

    Read() 调用依赖于您的操作系统行为。它的行为依赖于套接字行为。

    如果你熟悉socket接口(这几乎是操作系统之间的一个标准,有一些小的差异),你会发现使用同步通信模式的socket,read系统调用总是阻塞线程的执行直到超时值过期,您无法更改此行为。

    Go 在底层使用同步 I/O 来满足其所有需求,因为 goroutine 使异步通信在设计上不需要。

    还有一种方法可以打破read:通过手动关闭套接字,这不是代码的最佳设计决策,并且在您的特定情况下。所以我认为你应该更好地使用更小的超时,或者重新设计你的代码以其他方式工作。

    【讨论】:

      【解决方案2】:

      除了SetReadDeadlineClose 连接之外,您真的无法停止Read 呼叫。

      您可以做的一件事是使用bufio 包对其进行缓冲。这将允许您 Peek 而不实际从缓冲区中读取某些内容。 Peek 将像 Read 一样阻止,但允许您决定当有内容可供阅读时要做什么。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-02-14
        • 1970-01-01
        • 2019-01-04
        • 2011-10-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多