-1

我想要一个用于游戏应用程序的 TCP 连接。有时间效率很重要。我想有效地接收许多对象。由于负载,CPU 效率也很重要。

到目前为止,我可以确保每次使用 go 的网络库拨打连接时都会调用 handleConnection。但是,一旦创建了连接,我就必须轮询(一遍又一遍地检查连接上是否准备好新数据)。这似乎效率低下。如果它不必要地占用 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()
}
4

1 回答 1

0

你说:

所以我想出了下面的代码,但它仍在使用 Decode(p) 调用检查新数据。

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

您可以在decoder.Decode.

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

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

于 2017-08-01T21:05:57.527 回答