1 回答
TA贡献1785条经验 获得超4个赞
Go 在编写网络服务的工具领域特别突出,因为它在运行时调度程序中集成了 I/O 感知功能,为任何正在运行的 GO 程序提供支持。
基本思想大致是这样的:goroutine 在套接字上执行正常的、顺序的、无回调的操作——即普通的读取和普通的写入——并且只要下一个 I/O 操作阻塞(是的,相关的系统调用在类 Unix 内核返回EWOULDBLOCK
) 时,goroutine 被挂起,它的套接字被分发到运行时的一个名为“netpoller”的组件中,该组件是使用平台原生套接字 I/O 多路复用器(例如 IOCP 或 IOCP)实现的epoll
,kqueue
并且goroutine 正在运行的操作系统线程被移交给另一个想要运行的 goroutine。一旦 netpoller 发出信号,套接字上的 I/O 导致 goroutine 暂停可以继续,调度程序将该 goroutine 排队等待执行,然后它继续在它停止的地方运行。
正因为如此,在 Go 中编写网络服务时采用的常用模型是每个套接字有一个 goroutine。当您编写普通的 TCP 服务器时,您应该自己创建一个 goroutine(并在它接受客户端连接后将侦听器返回的套接字交给它)。net/http.Server
内置了这种行为,因为它创建了一个 goroutine 来服务每个传入的客户端请求(实际上,对于 HTTP/1.x,每个连接创建两个甚至三个 goroutine,但它对 HTTP 请求处理程序是不可见的)。
现在,我们刚刚介绍了基础知识。当然,可能有正当理由需要额外的 goroutine 来处理完成请求所需执行的任务,这就是 @Volker 所指的。
- 1 回答
- 0 关注
- 129 浏览
添加回答
举报