中止来自另一个goroutine的Read()调用

时间:2013-07-28 22:35:19

标签: io go

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

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

有没有办法在Read()电话开始时停止,而不等待超时到期或类似的事情?

2 个答案:

答案 0 :(得分:0)

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

如果您熟悉套接字接口(这几乎是操作系统之间的标准差异很小),您会看到使用套接字的同步通信模式,read系统调用始终阻止线程的执行,直到超时值到期,您无法更改此行为。

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

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

答案 1 :(得分:0)

除非ReadSetReadDeadline连接,否则您停止 Close来电真的不多。

您可以做的一件事是使用bufio包缓冲它。这将允许您Peek而无需实际读取缓冲区中的内容。 Peek会像Read那样阻止,但会允许您决定在有什么内容可供阅读时做什么。