0

いくつかのバックグラウンド スレッドがあり、それらが IO 操作などを実行することはわかっています。その後、コールバックが呼び出されます。すべてのコールバックは 1 つのスレッドで呼び出されていますか (= 2 つのコールバックを同時に実行することはできません)? たとえば、uv_read_start( echo_read) に渡されるコールバックは、データがソケット接続に到達したときに呼び出される必要があります。常にメイン スレッドで呼び出され、それらのバックグラウンド スレッドはecho_readそのソケットからのデータのバッファリングにのみ使用されますか? でゲームサーバーを作成したいのですlibuvが、実際には、一度に処理されるゲームパケットは常に1つだけで、それ以上ではないことを確認する必要があります(そうしないと、多くの同期の問題が発生し、おそらく接地)。

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);
    }
}
4

1 に答える 1

1

はい、libuv イベント ループは、コールバックの処理が並列ではなく順次に行われることを保証します。

これは、ゲーム エンジンに適したイベント ループの重要なアイデアです。スレッドを同期する必要がないため、さまざまなロック メカニズムのコストを回避できます。データを変更すると、他のすべてのコールバックで一貫性が保たれます。

ただし、uv_run は 1 つのコアでしか実行されず、十分なスループットがあれば、1 つのコアしか汗をかくことはできません。

多数の接続 (MMPORG) を持つゲームのサーバー コードをコーディングしている場合は、コアごとに 1 つのスレッドを作成し、各スレッド内で UV イベント ループを実行する必要があります。カウンター ストライクのようなゲームの場合は、1 つのイベント ループで十分です。

于 2014-05-26T08:47:04.827 に答える