Networking 如何在net.Conn上执行非阻塞写入?

Networking 如何在net.Conn上执行非阻塞写入?,networking,go,nonblocking,Networking,Go,Nonblocking,如何在Go中对网络连接执行非阻塞写入 我认为可以通过在过去设定最后期限来实现: conn.SetWriteDeadline(time.Date(0, 0, 0, 0, 0, 0, 1, time.UTC)) n, err := conn.Write(buffer) 。。。但这只是由于“i/o超时”错误而失败,实际上没有向连接写入任何字节。在Go中,您使用阻塞i/o,运行时将其“转换”为非阻塞i/o:从套接字读取时被阻塞的goroutine将由调度程序与另一个goroutine交换,以便继续执行

如何在Go中对网络连接执行非阻塞写入

我认为可以通过在过去设定最后期限来实现:

conn.SetWriteDeadline(time.Date(0, 0, 0, 0, 0, 0, 1, time.UTC))
n, err := conn.Write(buffer)

。。。但这只是由于“i/o超时”错误而失败,实际上没有向连接写入任何字节。

在Go中,您使用阻塞i/o,运行时将其“转换”为非阻塞i/o:从套接字读取时被阻塞的goroutine将由调度程序与另一个goroutine交换,以便继续执行

因此,您可以充分利用这两个方面:易于理解的代码(例如,无回调地狱)和非阻塞I/O的效率(即epoll、kqueue、完成端口)

更新:


@cpcallen我需要能够以这样一种方式写入套接字,即我可以确定执行写入的线程不会阻塞


如果通过“线程”引用操作系统级线程,则不会阻止它。如果通过“线程”引用执行写入的goroutine,这还不可能,但有一个建议:

在Go中,您使用阻塞I/O,运行时将其“转换”为非阻塞I/O:从套接字读取时阻塞的goroutine将由调度程序与另一个goroutine交换,以继续执行

因此,您可以充分利用这两个方面:易于理解的代码(例如,无回调地狱)和非阻塞I/O的效率(即epoll、kqueue、完成端口)

更新:


@cpcallen我需要能够以这样一种方式写入套接字,即我可以确定执行写入的线程不会阻塞


如果通过“线程”引用操作系统级线程,则不会阻止它。如果通过“线程”您指的是执行写入的goroutine,这还不可能,但有一个建议:

您不可能。这是一种狂欢的意义。你想做什么?而且截止日期已经过去很久了,所以它马上就过期了。你是说
time.Now().Add(1*time.Second)
?@JimB:在一次一个线程(类似字节码)的解释器中进行非阻塞写入。如果写操作阻塞,我将通知或挂起线程(并允许另一个线程运行)。我可以对通道进行非阻塞写入,这样我就可以通过为每个套接字提供一个专用的goroutine来间接实现我想要的功能,从而将字节从通道传输到套接字,但这似乎是一个愚蠢的额外开销(和复杂性),需要做一些应该非常直接的事情。@cpcallen:goroutine不是线程,对网络的阻塞写入不会阻塞整个线程。我不知道你说的“愚蠢的额外开销”是多少。@Adrian:不;将世界停止一秒钟是不可接受的,如果试图将超时调整到尽可能小的程度,则可能会出现写入操作,从而不会不必要地阻止失败。这是一种狂欢的意义。你想做什么?而且截止日期已经过去很久了,所以它马上就过期了。你是说
time.Now().Add(1*time.Second)
?@JimB:在一次一个线程(类似字节码)的解释器中进行非阻塞写入。如果写操作阻塞,我将通知或挂起线程(并允许另一个线程运行)。我可以对通道进行非阻塞写入,这样我就可以通过为每个套接字提供一个专用的goroutine来间接实现我想要的功能,从而将字节从通道传输到套接字,但这似乎是一个愚蠢的额外开销(和复杂性),需要做一些应该非常直接的事情。@cpcallen:goroutine不是线程,对网络的阻塞写入不会阻塞整个线程。我不知道你说的“愚蠢的额外开销”是多少。@Adrian:不;停止世界一秒钟是不可接受的-尝试将超时调整到尽可能小的程度可能会导致写入操作不被不必要地阻止失败。我需要能够以这样的方式写入套接字,以确保执行写入操作的线程不会被阻止。@cpcallen更新了我的答案,以解决您的问题是的:在我的评论中,我说的是线程,但意思是goroutine。很好的问题点/15735,但我认为这是没有阅读的阻塞,不是在不阻塞的情况下写入…@Agis在调用阻塞的系统调用时指的是阻塞的goroutine和os级线程。我需要能够以这样的方式写入套接字,以便我可以确定执行写入的线程不会阻塞。@cpcallen更新了我的答案,回答了您的评论。是的:在我的评论中,我说了thread,但是意思是戈鲁廷。很好地解决了问题/15735,但我认为这是在不读的情况下阻塞,而不是在不阻塞的情况下写入…@Agis在调用阻塞系统调用goroutine和os级线程阻塞时提到。