libuv中handle在不同的loop之间transfer

本文介绍如何使用Libuv库实现TCP和UDP handle在不同线程间的迁移,通过示例代码展示了如何在一个线程中监听连接请求,在另一个线程中进行读写操作,以此提高程序性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 对于udp,tcp的handle是可以在不同的loop之间transfer,转移时使用函数uv_udp_init_ex和uv_tcp_init_ex初始化,将handle的flags传入进去即可。 eg:主线程负责监听接受连接请求,另一个线程用传递来的handle,监听读写(防止主线程监听事件过多而影响性能,将部分监视器分配到子线程中去)

  • #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <uv.h>


    uv_loop_t* loop1;
    uv_loop_t* loop2;
    uv_async_t async;


    void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
    buf->base = (char*)malloc(suggested_size);
    buf->len = suggested_size;
    }


    void echo_write(uv_write_t *req, int status) {
    if (status) {
    fprintf(stderr, "Write error %s\n", uv_strerror(status));
    }
    free(req);
    }


    void echo_read(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf) {


    if (nread < 0) {
    if (nread != UV_EOF)
    //fprintf(stderr, "Read error %s\n", uv_err_name(nread));
    uv_close((uv_handle_t*)client, NULL);
    }
    else if (nread > 0) {
    uv_write_t *req = (uv_write_t *)malloc(sizeof(uv_write_t));
    uv_buf_t wrbuf = uv_buf_init(buf->base, nread);
    printf("read buf:%s\n", buf->base);
    uv_write(req, client, &wrbuf, 1, echo_write);
    }


    if (buf->base)
    free(buf->base);
    }


    void on_new_connection(uv_stream_t *server, int status) {
    if (status < 0) {
    fprintf(stderr, "New connection error %s\n", uv_strerror(status));
    return;
    }
    char cliIp[17] = { 0 };
    int  cliPort = 0;


    uv_tcp_t *client = (uv_tcp_t*)malloc(sizeof(uv_tcp_t));
    uv_tcp_init(loop1, client);
    if (uv_accept(server, (uv_stream_t*)client) == 0) {


    async.data = (void*)client;
    uv_async_send(&async);
    }
    else {


    uv_close((uv_handle_t*)client, NULL);
    }
    }


    void async_cb(uv_async_t* handle)
    {
    printf("async_cb called!\n");
    uv_tcp_t* client = (uv_tcp_t*)handle->data;

    uv_tcp_init_ex(loop2, client, client->flags);
    uv_read_start((uv_stream_t*)client, alloc_buffer, echo_read);


    }


    void threadFunc(void* arg)
    {
    loop2 = uv_default_loop();
    uv_thread_t id = uv_thread_self();
    printf("threadFunc id:%lu.\n", (unsigned long)id);


    uv_async_init(loop2, &async, async_cb);


    uv_run(loop2, UV_RUN_DEFAULT);
    }


    int main() {
    loop1 = uv_default_loop();


    uv_thread_t id = uv_thread_self();
    printf("thread id:%lu.\n", id);


    //创建子线程  
    uv_thread_t thread;
    uv_thread_create(&thread, threadFunc, NULL);
    uv_tcp_t server;
    struct sockaddr_in addr;
    uv_tcp_init(loop1, &server);


    uv_ip4_addr("127.0.0.1", 7000, &addr);


    uv_tcp_bind(&server, (const struct sockaddr*)&addr, 0);
    int r = uv_listen((uv_stream_t*)&server, 2, on_new_connection);
    if (r) {
    fprintf(stderr, "Listen error %s\n", uv_strerror(r));
    return 1;
    }
    uv_run(loop1, UV_RUN_DEFAULT);


    uv_thread_join(&thread);    //等待子线程完成
    getchar();
    printf("main thread end!\n");

    return 0;
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值