文章目录

libhv简介 libhv应用程序框架 libhv事件循环使用入门 libhv日志模块介绍 libhv如何实现跨平台的 libhv中的宏艺术 golang defer 宏实现 libhv多线程同步相关知识 c语言如何实现c++的继承 libevent、libev、libuv、libhv、boost.asio、poco、muduo七种echo-server实现对比 libhv事件循环逻辑

libhv简介

libhv是一个跨平台的类似libevent、libev、libuv的异步事件驱动库,但提供了更加接近原生的API接口和更加丰富的协议。
libhv已广泛实用在公司的IOT平台、http API服务之中,正确性、稳定性、可扩展性、性能都有保证,完全开源,请放心使用。

739352073

libhv应用程序框架

libhv提供了命令行解析、INI配置文件解析、日志文件、pid文件、信号处理等创建一个应用程序的常用模块

main.cpp.tmpl

测试示例:

make test
bin/test -h
bin/test -v
bin/test -t
bin/test -d
ps aux | grep test
bin/test -s status
bin/test -s stop
ps aux | grep test
bin/test -s start -d
ps aux | grep test
bin/test -s restart -d
ps aux | grep test

流程图:

libhv事件循环使用入门

examples/loop.cexamples/timer.cexamples/tcp.cexamples/udp.cexamples/nc.c
make loop timer tcp udp nc
bin/loop
bin/timer
bin/tcp 1111
bin/nc 127.0.0.1 1111
bin/udp 2222
bin/nc -u 127.0.0.1 2222

流程图:

libhv日志模块介绍

libhv如何实现跨平台的

./configurehconfig.hHAVE_PTHREAD_HHAVE_GETTIMEOFDAYbase/hplatform.h_WIN32__linux____GNUC____clang___MSC_VER__i386____x86_64____arm____aarch64____cplusplus
base/htime.c

libhv中的宏艺术

C语言宏基础知识
宏是C/C++语言的一大特色,它将一个标识符定义为一个字符串,在预处理阶段源程序中的该标识符均以指定的字符串来代替,使用宏可以使代码更加简洁和增强可读性。

#define <宏名> (<参数表>) <宏体>
#undef <宏名>

#ifdef <宏名>
    ...
#else
    ...
#endif

//define中的三个特殊符号:#,##,#@
#define STRCAT(x,y) x##y //连接x和y成一个字符串
#define TOCHAR(x) #@x  //给x加上单引号
#define TOSTR(x) #x //给x加上双引号
base/herr.hbase/herr.c
#define FOREACH_ERR_COMMON(F)   \
    F(0,    OK,             "OK")               \
    F(1000, UNKNOWN,        "Unknown error")    \
    \
    F(1001, NULL_PARAM,     "Null parameter")   \
    F(1002, NULL_POINTER,   "Null pointer")     \
    F(1003, NULL_DATA,      "Null data")        \
    F(1004, NULL_HANDLE,    "Null handle")      \
    \
    F(1011, INVALID_PARAM,      "Invalid parameter")\
    F(1012, INVALID_POINTER,    "Invalid pointer")  \
    F(1013, INVALID_DATA,       "Invalid data")     \
    F(1014, INVALID_HANDLE,     "Invalid handle")   \
    F(1015, INVALID_JSON,       "Invalid json")     \
    F(1016, INVALID_XML,        "Invalid xml")      \
    F(1017, INVALID_FMT,        "Invalid format")   \
    F(1018, INVALID_PROTOCOL,   "Invalid protocol") \
    F(1019, INVALID_PACKAGE,    "Invalid package")  \

#define FOREACH_ERR(F)      \
    FOREACH_ERR_COMMON(F)   \
    FOREACH_ERR_FUNC(F)     \
    FOREACH_ERR_SERVICE(F)  \
    FOREACH_ERR_GRPC(F)     \

#undef ERR_OK // prevent conflict
enum {
#define F(errcode, name, errmsg) ERR_##name = errcode,
    FOREACH_ERR(F)
#undef  F
};
// errcode => errmsg
const char* hv_strerror(int err) {
    if (err > 0 && err <= SYS_NERR) {
        return strerror(err);
    }

    switch (err) {
#define F(errcode, name, errmsg) \
    case errcode: return errmsg;
    FOREACH_ERR(F)
#undef  F
    default:
        return "Undefined error";
    }
}
hv_strerrorcase errcode: return errmsg;

golang defer 宏实现

deferbase/hscope.h
// same as golang defer
class Defer {
public:
    Defer(Function&& fn) : _fn(std::move(fn)) {}
    ~Defer() { if(_fn) _fn();}
private:
    Function _fn;
};
#define defer(code) Defer STRINGCAT(_defer_, __LINE__)([&](){code});

libhv多线程同步相关知识

base/hthread.hbase/hmutex.hunittest/hmutex_test.cbase/hmutex.h
make unittest
bin/hmutex

c语言如何实现c++的继承

event/hloop.hevent/hevent.h

libevent、libev、libuv、libhv、boost.asio、poco、muduo七种echo-server实现对比

libevent、libev、libuv、libhv、boost.asio、poco、muduo

编译参考README.md 中的echo-servers/benchmark

make libhv
make webbench
# ubuntu16.04
sudo apt-get install libevent-dev libev-dev libuv1-dev libboost-dev libasio-dev libpoco-dev
# muduo install => https://github.com/chenshuo/muduo.git
make echo-servers
sudo echo-servers/benchmark.sh

压力测试结果图:

注:客户端和服务端位于同一台电脑,有一定随机性,仅供参考,总的来说,这几个库性能接近,各有千秋吧

libhv事件循环逻辑

int hloop_run(hloop_t* loop) {
    loop->status = HLOOP_STATUS_RUNNING;
    while (loop->status != HLOOP_STATUS_STOP) {
        if (loop->status == HLOOP_STATUS_PAUSE) {
            msleep(PAUSE_TIME);
            hloop_update_time(loop);
            continue;
        }
        ++loop->loop_cnt;
        if (loop->nactives == 0) break;
        hloop_process_events(loop);
        if (loop->flags & HLOOP_FLAG_RUN_ONCE) {
            break;
        }
    }
    loop->status = HLOOP_STATUS_STOP;
    loop->end_hrtime = gethrtime();
    if (loop->flags & HLOOP_FLAG_AUTO_FREE) {
        hloop_cleanup(loop);
        SAFE_FREE(loop);
    }
    return 0;
}
hloop_runhloop_process_events
star