Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/flash/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Io 中止来自另一个goroutine的Read()调用_Io_Go - Fatal编程技术网

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

Io 中止来自另一个goroutine的Read()调用,io,go,Io,Go,我正在使用IMAP服务器,其中一个操作是升级连接以使用TLS(通过STARTTLS命令)。我们当前的架构有一个goroutine从套接字读取数据,解析命令,然后通过通道发送逻辑命令。另一个goroutine从该通道读取并执行命令。总的来说,这很有效 但是,在执行STARTTLS时,我们需要停止当前正在进行的Read()调用,否则Read()将消耗TLS握手的字节数。我们可以在这两个类之间插入另一个类,但是该类将在Read()调用中被阻塞,我们也有同样的问题。如果网络连接是一个通道,我们可以添加另

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

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

有什么方法可以在调用开始后立即停止它,而不必等待超时过期或类似的情况?

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

如果您熟悉socket接口(这几乎是操作系统之间的标准接口,但有一些小的差异),您将看到对socket使用同步通信模式,
read
系统调用总是在超时值过期之前阻止线程的执行,并且您无法更改此行为

Go在后台使用同步I/O来满足其所有需求,因为goroutines使异步通信成为设计所不需要的


还有一种方法可以断开<代码>读取:手动关闭套接字,这不是代码的最佳设计决策,在您的特定情况下也是如此。因此,我认为,您最好使用较小的超时时间,或者重新设计代码,以其他方式工作。

要停止
读取
呼叫,您实在无能为力,除非您
设置读取截止日期
,或者
关闭连接

您可以做的一件事是使用
bufio
包对其进行缓冲。这将允许您在不实际读取缓冲区中的内容的情况下进行操作
Peek
将像
Read
一样进行阻止,但允许您决定在可以读取某些内容时执行什么操作