How can I perform a non-blocking write on a net.Conn?

huangapple go评论92阅读模式
英文:

How can I perform a non-blocking write on a net.Conn?

问题

在Go语言中,你可以通过设置写入截止时间来实现非阻塞写入网络连接。你可以将截止时间设置为过去的时间来实现非阻塞写入:

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

然而,这种方法只会导致"i/o timeout"错误,而不会实际向连接中写入任何字节。

英文:

How can I perform a non-blocking write on a network connection in Go?

I thought it might be possible to do so by setting the deadline in the past:

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

... but this just fails with an 'i/o timeout' error without actually writing any bytes to the connection.

答案1

得分: 3

在Go语言中,你使用阻塞式I/O,而运行时会将其“转换”为非阻塞式I/O:当一个goroutine在从套接字读取时被阻塞,调度器会将其与另一个准备好继续执行的goroutine进行交换。

因此,你可以同时获得两全其美的好处:易于跟踪的代码(例如,没有回调地狱)和非阻塞式I/O的效率(即epoll、kqueue、完成端口)。

更新:

> @cpcallen 我需要以一种确保执行写操作的线程不会被阻塞的方式向套接字写入数据。

如果你指的是操作系统级别的线程,那么它不会被阻塞。如果你指的是执行写操作的goroutine,目前还不可能,但有一个提案:https://github.com/golang/go/issues/15735

英文:

In Go you use blocking I/O and the runtime "converts" it to non-blocking I/O: a goroutine blocked while reading from a socket, will be swapped by the scheduler with another goroutine ready to continue its execution.

Thus, you get the best of both worlds: code that's easier to follow (eg. no callback hell) and the efficiency of non-blocking I/O (ie. epoll, kqueue, completion ports).

UPDATE:

> @cpcallen I need to be able to write to a socket in such a way that I can be certain that the thread performing the write does not block.

If by "thread" you refer the OS-level thread, it is not blocked. If by "thread" you refer to the goroutine performing the write, that's not yet possible but there's a proposal: https://github.com/golang/go/issues/15735

huangapple
  • 本文由 发表于 2017年5月27日 03:53:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/44209241.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定