/async

c++异步io

Primary LanguageC++

c++异步io库

编译:
1、 如需使用redis模块,则cmake时需定义宏USE_ASYNC_REDIS。如:cmake .. -DUSE_ASYNC_REDIS=1
    redis模块依赖:libevent、hiredis_vip、hiredis库

2、 如需使用mongo模块,则cmake时需定义宏USE_ASYNC_MONGO。如:cmake .. -DUSE_ASYNC_MONGO=1
    monogo模块依赖: bson-1.0、mongoc-1.0库

3、 如需使用libcurl模块,则cmake时需定义宏USE_ASYNC_CURL。如:cmake .. -DUSE_ASYNC_CURL=1
    libcurl模块依赖: libcurl库

4、 如需使用mysql模块,则cmake时需定义宏USE_ASYNC_MYSQL。如:cmake .. -DUSE_ASYNC_MYSQL=1
    mysql模块依赖:mariadb库, 安装命令:yum install -y mariadb-devel.x86_64

5、 如需使用ipc模块,则cmake时需定义宏USE_IPC。如:cmake .. -DUSE_IPC=1
    ipc模块依赖:zeromq库

6、 如需使用transaction模块,则cmake时需定义宏USE_TRANS。如:cmake .. -DUSE_TRANS=1
    transaction模块依赖:无依赖

7、 如需使用net模块,则cmake时需定义宏USE_NET。如: cmake .. -DUSE_NET=1
    net模块依赖:libevent

8、cmake例子:
    1)根目录下执行:mkdir -p build
    2)cd build
    3)cmake .. -DUSE_ASYNC_CURL=1 -DUSE_ASYNC_REDIS=1 -DUSE_ASYNC_MONGO=1 \
        -DUSE_ASYNC_MYSQL=1 -DUSE_IPC=1 -DUSE_TRANS=1 -DUSE_NET=1 -DCMAKE_BUILD_TYPE=Debug

依赖库安装:
    如果库安装路径、链接版本、头文件等出现报错,可以根据编译环境调整 common/CMakeLists.txt文件

目录结构:
example
    example.cpp         ----> 测试用例
    CMakeLists.txt      ----> 编译文件

common                  ----> 库目录
    threads             ----> 线程池目录
        thread_pool.h   ----> 线程池类
    
    coroutine           ----> 协程目录
        coroutine_task.h/cpp ----> 协程池类文件
        coroutine.h/cpp ----> 协程
    
    async               ----> 异步库目录
        cpu             ----> 异步cpu运算实现
        curl            ----> 异步http实现
        mongo           ----> 异步mongo实现
        mysql           ----> 异步mysql实现
        redis           ----> 异步redis实现

    co_async            ----> 协程与异步io的结合
        promise         ----> 支持将异步操作变成同步操作,有点类似于js中的promise
        cpu             ----> async::cpu与promise的结合
        curl            ----> async::curl与promise的结合
        mongo           ----> async::mongo与promise的结合
        mysql           ----> async::mysql与promise的结合
        redis           ----> async::redis与promise的结合
        ipc              ----> 用以提供进程间通信时协程式的send接口

    ipc                 ----> 提供进程间的通信,适合用于后端服务之间的通信。使用zeromq库作为实现者

    transaction         ----> 提供以协程方式运行的包处理接口

    net                 ----> 提供tcp server/client接口,udp server/client接口,http server接口

serve                   ----> 目标是提供一个服务器进程脚手架,可以快速搭建后端服务,还提供一个通用的route进程。
                              它会依赖common库,且common库需要使用-DUSE_TRANS编译。已实现大部分功能
    serve               ----> 编译输出libserve.so库
    route               ----> ./router -c router.json 启动路由,不同世界的路由互不通信
    test                ----> 测试案例,起两个进程,这两个进程使用router做转发相互通信。
    testhttp            ----> 演绎如何监听http服务,并注册httptransaction处理业务
                              
层次结构:co表示coroutine协程

                              co_async
            ________________________________________________
            |      |        |        |         |          |
        ____|      |        |        |         |          |_
       |           |        |        |         |           |
     co_redis   co_mongo   co_curl  co_cpu   co_mysql   parallel接口
       |           |        |        |         |           |
       |           |        |        |         |           |
       |           |        |        |         |           |
       -----------------------------------------------------
       |                      promise                      |
       -----------------------------------------------------
       |           |        |        |         |           |
async_redis  async_mongo async_curl async_cpu async_mysql  |
       |           |        |        |         |           |
       |           |        |        |         |           |
       -----------------------------------------------------
                                    |
                                    |
                             thread_pool(*可选用)      

线程池是选用模块,建议使用,能使异步io运行速度变快。
如果不使用,则由调用线程来驱动异步io的运行

example:
// 下面代码的输出结果是:
promise begin
异步执行结束
promise over:0

void promise_test() {
    // 起一个协程任务,回调将在协程里运行
    CoroutineTask::doTask([](void*){
        printf("promise begin\n");
        auto ret = co_async::promise([](co_async::Resolve resolve, co_async::Reject reject) {
            // 两秒后执行下面的回调
            co_async::setTimeout([resolve]() {
                printf("异步执行结束\n");
                // 报告promise异步执行结束,并传递结果集,这里传nullptr
                resolve(nullptr);
            }, 2*1000);
        }, 10 * 1000);
        // promise返回,往下继续走
        printf("promise over:%d\n", ret.first);
    }, 0);
}

int main() {
    promise_test();
    //cpu_test(true);
    //co_parallel_test();
    //curl_test(true);
    //mongo_test(true);
    //redis_test(true);
    //co_mysql_test();
    //ipc_test();

    while (true) {
        co_async::loop();
        usleep(100);
        //printf("loop\n");
    }
    return 0;
}

///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////

serve模块的使用案例步骤:

1、启动router进程: ./router -c router.json
router.json的配置如下:
{
    "comment": "本配置文件描述的是进程监听及连接端口的信息",

    "@zm_listen": "zeromq的监听信息列表, 一般是给路由使用",
    "zm_listen": [
        {
            "world": 1,
            "protocol": "tcp",
            "ip": "0.0.0.0",
            "port": 5001
        }
    ],

    "@routes": "描述的是将会连接到本进程的连接信息,以便做路由选择使用",
    "routes": [
        {
            "world": 1,
            "type": 1,
            "id": 1
        },
        {
            "world": 1,
            "type": 2,
            "id": 1
        }
    ]
}

2、启动testServe1进程:./testServe -c serve1.json
serve1.json的配置如下:
{
    "comment": "本配置文件描述的是进程监听及连接端口的信息",

    "@self": "标识进程身份的信息",
    "self": {
        "world": 1,
        "type": 1,
        "id": 1
    },

    "@zm_connect": "zeromq的连接信息列表",
    "zm_connect": [
        {
            "protocol": "tcp",
            "ip": "0.0.0.0",
            "port": 5001
        }
    ]
}

3、启动testServe2进程:./testServe -c serve2.json
serve1.json的配置如下:
{
    "comment": "本配置文件描述的是进程监听及连接端口的信息",

    "@self": "标识进程身份的信息",
    "self": {
        "world": 1,
        "type": 2,
        "id": 1
    },

    "@zm_connect": "zeromq的连接信息列表",
    "zm_connect": [
        {
            "protocol": "tcp",
            "ip": "0.0.0.0",
            "port": 5001
        }
    ]
}