为了账号安全,请及时绑定邮箱和手机立即绑定

从另一个 goroutine 中止 Read() 调用

从另一个 goroutine 中止 Read() 调用

Go
aluckdog 2021-06-07 17:23:33
我正在 IMAP 服务器上工作,其中一项操作是升级连接以使用 TLS(通过STARTTLS命令)。我们当前的架构有一个 goroutine 从套接字读取数据,解析命令,然后通过通道发送逻辑命令。另一个 goroutine 从该通道读取并执行命令。这在一般情况下效果很好。STARTTLS但是,在执行时,我们需要停止当前正在进行的Read()调用,否则Read()会消耗 TLS 握手中的字节。我们可以在两者之间插入另一个类,但是该类将在Read()调用时被阻塞,我们遇到了同样的问题。如果网络连接是一个通道,我们可以添加另一个信号通道并使用一个select{}块来停止读取,但网络连接不是通道(并且简单地将它包装在一个 goroutine 中,通道只是将问题移到那个 goroutine 上)。有没有办法在Read()通话开始后停止通话,而无需等待超时到期或类似的事情?
查看完整描述

2 回答

?
料青山看我应如是

TA贡献1772条经验 获得超8个赞

这里真的没有什么可以做,以阻止一个Read电话,除非你SetReadDeadline,或者Close连接。

你可以做的一件事是用bufio包缓冲它。这将允许您在不实际从缓冲区中读取内容的情况下进行PeekPeek会像Readdo一样阻塞,但允许您决定在某些内容可供阅读时做什么。


查看完整回答
反对 回复 2021-06-21
?
慕森卡

TA贡献1806条经验 获得超8个赞

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

如果您熟悉socket接口(这几乎是操作系统之间的标准,但有一些细微差别),您会看到使用socket同步通信模式,read系统调用总是阻塞线程的执行,直到超时值到期,您可以不要改变这种行为。

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

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


查看完整回答
反对 回复 2021-06-21
  • 2 回答
  • 0 关注
  • 227 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信