c - 游戏服务器的 uvlib

标签 c node.js libuv

我知道有一些后台线程,它们执行 IO 操作等,之后,我的回调被调用。是否所有回调都在一个线程中调用(= 两个回调不能同时执行)? 例如,传递给 uv_read_start (echo_read) 的回调,当数据来自套接字连接时,应该调用该回调。 echo_read 是否始终在主线程中调用,而这些后台线程仅用于缓冲来自该套接字的数据? 我想使用 libuv 创建游戏服务器,但实际上我需要确定,一次总是只处理一个游戏数据包,而不是更多(否则会出现很多同步问题,我可能需要从头开始实现)。

int main() {
    loop = uv_default_loop();

    uv_tcp_t server;
    uv_tcp_init(loop, &server);

    struct sockaddr_in bind_addr = uv_ip4_addr("0.0.0.0", 7000);
    uv_tcp_bind(&server, bind_addr);
    int r = uv_listen((uv_stream_t*) &server, 128, on_new_connection);
    if (r) {
        fprintf(stderr, "Listen error %s\n", uv_err_name(uv_last_error(loop)));
        return 1;
    }
    return uv_run(loop, UV_RUN_DEFAULT);
}

void on_new_connection(uv_stream_t *server, int status) {
    if (status == -1) {
        // error!
        return;
    }

    uv_tcp_t *client = (uv_tcp_t*) malloc(sizeof(uv_tcp_t));
    uv_tcp_init(loop, client);
    if (uv_accept(server, (uv_stream_t*) client) == 0) {
        uv_read_start((uv_stream_t*) client, alloc_buffer, echo_read);
    }
    else {
        uv_close((uv_handle_t*) client, NULL);
    }
}

最佳答案

是的,libuv 事件循环保证回调的处理是顺序完成的,而不是并行的。

这是事件循环的关键思想,这使得它们适合游戏引擎,因为您不需要同步线程,从而避免了各种锁定机制的成本。如果您对数据进行修改,它们将在所有其他回调上保持一致。

但是,uv_run 将仅在一个核心上运行,并且具有足够的吞吐量,它将只能使一个核心出汗。

如果您正在为具有大量连接的游戏 (MMPORG) 编写服务器代码,那么您将需要为每个核心创建一个线程,并在每个核心中运行 uv 事件循环。如果我们谈论的是像《反恐精英》这样的游戏,一个事件循环就足够了。

关于c - 游戏服务器的 uvlib,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22289921/

相关文章:

c - 用FD_SET制作读写集,用于在C中发送和接收数据

javascript - 从 mongodb 作为文档检索对象类型后如何获取对象类型?

node.js - 为什么libuv通过多线程进行DNS请求

c - Windows 命名管道客户端上的 uv_start_read 等待服务器关闭其管道并导致 EOF

linux - 为什么 node.js+mongodb 不为每秒发送 100 个请求提供 100 个请求/秒的吞吐量?

c# - 在 C# 中使用 C 结构体

C++ 编译器错误无法访问类 'std::basic_ios<_Elem,_Traits>' 中声明的私有(private)成员

javascript - 如何在 JS( Node )中使用回调来等待异步函数完成后再继续?

javascript - 错误 : Missing credentials in config -/nodeapp/node_modules/aws-sdk/lib/request. js:31

c++ - 只有 wWinMain MSVC 2019 的链接器错误无法解析的外部符号