Как эффективно декодировать гобов и ждать, пока еще не прибудут через TCP-соединение
Я хотел бы иметь TCP-соединение для игрового приложения. Важно быть эффективным по времени. Я хочу получить много объектов эффективно. Также важно быть эффективным ЦП из-за нагрузки.
Пока что я могу убедиться, что handleConnection вызывается каждый раз, когда соединение набирается с использованием библиотеки go сети. Однако, как только соединение создано, я должен опрашивать (проверять снова и снова, чтобы увидеть, готовы ли новые данные для соединения). Это кажется неэффективным. Я не хочу запускать эту проверку, чтобы увидеть, готовы ли новые данные, если они излишне загружают процессор.
Я искал что-то вроде следующих двух вариантов, но не нашел то, что искал.
(1) Выполните операцию чтения, которая каким-то образом блокирует (не высасывая ЦП), а затем разблокирует, когда новый материал готов в потоке соединения. Я не мог найти это.
(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()
}
1 ответ
Ты говоришь:
Итак, я придумал приведенный ниже код, но он все еще выполняет большую проверку новых данных с помощью вызова Decode (p).
Почему вы так думаете? Декодер gob выдаст Read
к соединению и дождитесь, пока он вернет данные, прежде чем выяснить, что это такое и расшифровать. Это операция блокировки, и она будет обрабатываться асинхронно во время выполнения за кулисами. Программа будет спать до тех пор, пока не поступит соответствующий сигнал ввода-вывода. Вам не нужно делать что-то необычное, чтобы сделать это более производительным.
Вы можете проследить это самостоятельно в коде для decoder.Decode
,
Я думаю, что ваш код будет работать просто отлично. Процессор будет простаивать, пока не получит больше данных.
Идти не узел. Каждый API по большей части "блокирует", но это не такая большая проблема, как на других платформах. Среда выполнения управляет процедурами очень эффективно и по мере необходимости передает соответствующие сигналы спящим функциям.