zoukankan      html  css  js  c++  java
  • 发布一个modern c++ 编写的网络库

    uv-cpp是一个基于libuv的C++封装网络库,基于本人实际项目需求开发并使用。接口较为简单易用,并对libuv一些特性做了扩展及优化。压测结果稳定、高效。暂未发现内存泄漏及崩溃等相关bug。

    • 为什么需要封装libuv

    截至目前,C++没有标准网络库,常见的有ACE和boost.asio。ACE较为庞大臃肿,封装复杂,个人不推荐。boost.asio是boost库的一部分,需要依赖boost的部分实现,使用asio需要在项目引入较为庞大的boost库(虽然也可以脱离boost,个人不太习惯asio的接口)。而C语言的网络库主要有libevent、libev及libuv。libuv是nodejs的底层,较为成熟。所以如果在项目需要一套轻量级,且没有太多依赖的网络组件,最好的办法,还是自己封装一套。

    1.实现了C++功能的回调

    首先libuv是一个C语言库,意味着回调函数是C语言的回调,所以直接使用libuv网络消息回调,相关对象必须是全局的或者static对象,这是令人难以容忍的。这里通过libuv的用户数据功能实现了C++风格的回调,回调函数可以类成员函数,或者lambda。同时封装了TcpServer及TcpClient等类,简化编程。

    2.对线程安全做了优化

    libuv是一个非线程安全的库,跨线程发送数据数不允许的。uv-cpp中实现了线程安全的跨线程write数据操作。基于libuv的async异步机制实现,同时在跨线程调用时候会检查当前调用线程,如果在该loop线程中则直接发送,减少了不必要的性能损耗。实现如下:

    void uv::EventLoop::runInThisLoop(const std::function<void()>& func)
    {
        if (nullptr == func)
        return;
    
        if (isRunInLoopThread())
        {
            func();
            return;
        }
        async_->runInThisLoop(func);
    }
    

    同时libuv的aysnc接口存在多次调用只执行一次的可能(特性),比如有些操作需要在回调里面释放数据,这样就会内存泄漏。uv-cpp中的Async类优化这个问题,确保每次调用一定会被执行。

    3.实现了定时器及时间轮

    对libuv定时器做了一层封装,并实现了一个时间复杂度O(1)的时间轮,用于检测心跳超时。

    4.实现整包发送/接受协议机制

    实现了ListBuffer和CycleBuffe两种缓存机制,用于解决TCP的粘包及残包。数据会重新组成完整的包数据用于读取。性能测试显示CycleBuffe会损失20%~30%的性能。

    5日志接口

    uv-cpp没有实现日志功能,但是保留了接口,可以注册/绑定到自定义日志库中使用。

    详见example文件夹:https://github.com/wlgq2/uv-cpp/tree/master/example

  • 相关阅读:
    装饰器模式(Decorator)
    原语:从0到1,从硬件指令集到OS原语,锁原语的哲学
    从Oop-Klass模型看透反射
    从三数之和看如何优化算法,递推-->递推加二分查找-->递推加滑尺
    单例模式-静态内部类实现及原理剖析
    单例模式-DCL双重锁检查实现及原理刨析
    二分查找java实现
    I/O管理杂记
    PCB WCF Web接口增减参数后,在客户端不更新的情况,是否影响客户端,评估测试
    PCB MS SQL 排序应用(row_number rank dense_rank NTILE PARTITION)
  • 原文地址:https://www.cnblogs.com/hebaichuanyeah/p/11093879.html
Copyright © 2011-2022 走看看