如何有效地解码 gob 并等待更多通过 tcp 连接到达



我想为游戏应用程序建立TCP连接。节省时间很重要。我想有效地接收许多对象。由于负载,提高 CPU 效率也很重要。

到目前为止,我可以确保每次使用 go 的网络库拨号连接时都会调用句柄连接。但是,一旦创建了连接,我必须轮询(一遍又一遍地检查连接上是否准备好了新数据(。这似乎效率低下。我不想运行该检查以查看新数据是否准备就绪,如果它不必要地占用CPU。

我一直在寻找以下两个选项之类的东西,但没有找到我要找的东西。

(1( 执行读取操作,以某种方式阻塞(不吸 CPU(,然后在连接流上有新内容准备就绪时取消阻塞。我找不到。

(2( 执行异步方法,即在新数据到达连接流时调用函数(而不仅仅是在拨打新连接时(。我找不到。

我不想在这里放任何睡眠电话,因为这会增加响应单身消息的延迟。

我还考虑过为每条消息拨出,但我不确定这是否有效。

所以我想出了下面的代码,但它仍然使用 Decode(p( 调用对新数据进行大量检查,这似乎不是最佳的。

如何更有效地完成此操作?

func handleConnection(conn net.Conn) {
dec := gob.NewDecoder(conn)
p := &P{}
for {
result := dec.Decode(p)
if result != nil {
// do nothing
} else {
fmt.Printf("Received : %+v", p)
fmt.Println("result", result, "n")
}
}
conn.Close()
}

你说:

所以我想出了下面的代码,但它仍然使用 Decode(p( 调用对新数据进行大量检查。

你为什么这么认为?gob 解码器将向 conn 发出Read并等待它返回数据,然后再弄清楚它是什么并对其进行解码。这是一个阻塞操作,将由后台的运行时异步处理。goroutine将休眠,直到相应的io信号进入。您不必做任何花哨的事情来使其性能更高。

您可以在代码中自行跟踪此内容以进行decoder.Decode

我认为您的代码可以正常工作。CPU 将处于空闲状态,直到它收到更多数据。

Go 不是节点。每个 API 在大多数情况下都在"阻塞",但这并不像其他平台那样是一个问题。运行时非常有效地管理 goroutine,并根据需要将适当的信号委托给睡眠的 goroutine。

最新更新