首页 > 编程语言 > 详细

C++ 基础库 co v2.0 正式发布(协程库,日志库,JSON,网络编程...)

时间:2021-05-30 10:55:20      阅读:31      评论:0      收藏:0      [点我收藏+]

github.com/idealvin/co

Basic?(English)

co 是一个优雅、高效的 C++ 基础库,支持 Linux, Windows 与 Mac 平台,它包含协程库、网络库、日志库、命令行与配置文件解析库、单元测试框架、JSON 库等基本组件。

co 遵循极简的设计理念,提供的接口都尽可能简单明了,用户可以轻松上手。co 尽量避免过度封装,引入过多的概念,以减轻用户的学习负担,如 co 提供的协程化的 socket API,与原生 socket API 形式上基本一致,熟悉 socket 编程的用户,几乎不需要增加新的学习成本,就能轻松用这些 API 写出高性能的网络程序。

参考文档

亮点功能

协程(co)

co?是一个?golang?风格的 C++ 协程库,支持如下特性:

  • 多线程调度,默认线程数为系统 CPU 核数.

  • 协程共享栈(默认大小为 1MB),内存占用低,单机可轻松创建数百万协程.

  • 系统 api hook (Linux & Mac).

  • 协程锁?co::Mutex.

  • 协程同步事件?co::Event.

  • 协程池?co::Pool.

  • 协程化的?socket API.

  • 用?go()?创建协程:

    void?f()?{
    ????LOG?<<?"hello?world";
    }
    
    void?g(int?v)?{
    ????LOG?<<?"hello?"<<?v;
    }
    
    go(f);
    go(g,?777);

网络(so)

so?是基于协程的 C++ 网络库,提供一般的兼容 ipv6 的 TCP 框架,并实现了一个简单的基于 JSON 的 RPC 框架,另外还支持可选的 HTTP, HTTPS 与 SSL (需要 libcurl 与 openssl)。

  • 简单的静态 web server

    #include?"co/flag.h"
    #include?"co/log.h"
    #include?"co/so.h"
    
    DEF_string(d,?".",?"root?dir");?//?指定?web?server?根目录
    
    int?main(int?argc,?char**?argv)?{
    ????flag::init(argc,?argv);
    ????log::init();
    ????
    ????so::easy(FLG_d.c_str());?//?mum?never?have?to?worry?again
    
    ????return?0;
    }
  • http server (openssl?required for https)

    http::Server?serv;
    
    serv.on_req(
    ????[](const?http::Req&?req,?http::Res&?res)?{
    ????????if?(req.is_method_get())?{
    ????????????if?(req.url()?==?"/hello")?{
    ????????????????res.set_status(200);
    ????????????????res.set_body("hello?world");
    ????????????}?else?{
    ????????????????res.set_status(404);
    ????????????}
    ????????}?else?{
    ????????????res.set_status(405);?//?method?not?allowed
    ????????}
    ????}
    );
    
    serv.start("0.0.0.0",?80);????????????????????????????????????//?http
    serv.start("0.0.0.0",?443,?"privkey.pem",?"certificate.pem");?//?https
  • http client (libcurl?& zlib required)

    http::Client?c("http://127.0.0.1:7777");?//?http
    http::Client?c("https://github.com");????//?https,?openssl?required
    
    c.add_header("hello",?"world");??????????//?add?headers?here..c.get("/");
    LOG?<<?"response?code:?"?<<?c.response_code();
    LOG?<<?"body?size:?"?<<?c.body_size();
    LOG?<<?"Content-Length:?"?<<?c.header("Content-Length");
    LOG?<<?c.header();
    
    c.post("/hello",?"data?xxx");
    LOG?<<?"response?code:?"?<<?c.response_code();

日志库(log)

log?是一个高性能的本地日志系统。

  • 打印日志

    LOG?<<?"hello?"?<<?23;?//?info
    DLOG?<<?"hello"?<<?23;?//?debug
    WLOG?<<?"hello"?<<?23;?//?warning
    ELOG?<<?"hello?again";?//?error
  • 与 glog 的性能比较

    log vs gloggoogle glogco/log
    win2012 HHD1.6MB/s180MB/s
    win10 SSD3.7MB/s560MB/s
    mac SSD17MB/s450MB/s
    linux SSD54MB/s1023MB/s

上表是单线程连续打印 100 万条 info 日志(每条 50 字节左右)的测试结果,co/log?几乎快了?glog?两个数量级。

为何如此快?一是 log 库内部基于比?sprintf?快 8-25 倍的?fastream?实现,二是 log 库几乎没有什么内存分配操作。

命令行与配置文件解析(flag)

flag?是一个方便易用的命令行及配置文件解析库,支持自动生成配置文件。

  • 代码示例

    #include?"co/flag.h"
    
    DEF_int32(i,?32,?"comments");
    DEF_string(s,?"xxx",?"string?type");
    
    int?main(int?argc,?char**?argv)?{
    ????flag::init(argc,?argv);
    ????std::cout?<<?"i:?"?<<?FLG_i?<<?std::endl;
    ????std::cout?<<?"s:?"?<<?FLG_s?<<?std::endl;
    ????return?0;
    }
  • 编译后运行

    ./xx??????????????????????????#?以默认参数启动
    ./xx?-i=4k?-s="hello?world"???#?整数类型可以带单位?k,m,g,t,p,?不分大小写
    ./xx?-i?4k?-s?"hello?world"???#?与上等价./xx?--mkconf
    
    ./xx?--mkconf?????????????????#?自动生成配置文件?xx.conf
    ./xx?xx.conf??????????????????#?从配置文件?xx.conf?启动
    ./xx?-config?xx.conf??????????#?从配置文件?xx.conf?启动

json

json?是一个简单易用的高性能 json 库。最新版本将 Json 对象构建到一块连续的内存上,几乎不需要内存分配操作,大大提高了 json 的解析速度,可以达到 GB 每秒。

  • 代码示例
    #include?"co/json.h"
    
    //?Json:?{?"hello":"json",?"array":[123,?3.14,?true,?"nice"]?}
    json::Root?r;
    r.add_member("hello",?"json");????????//?add?key:value?pair
    json::Value?a?=?r.add_array("array");?//?add?key:array
    a.push_back(123,?3.14,?true,?"nice");?//?push?value?to?array,?accepts?any?number?of?parameters
    COUT?<<?a[0].get_int();???????????????//?123
    COUT?<<?r["array"][0].get_int();??????//?123
    COUT?<<?r["hello"].get_string();??????//?"json"
    fastring?s?=?r.str();?????????????????//?convert?Json?to?string
    fastring?p?=?r.pretty();??????????????//?convert?Json?to?human-readable?string
    json::Root?x?=?json::parse(s);????????//?parse?Json?from?a?string

代码构成

  • co/include

    libco?的头文件。

  • co/src

    libco?的源代码。

  • co/test

    一些测试代码,每个?.cc?文件都会编译成一个单独的测试程序。

  • co/unitest

    一些单元测试代码,每个?.cc?文件对应不同的测试单元,所有代码都会编译到单个测试程序中。

  • co/gen

    代码生成工具,根据 proto 文件,自动生成 rpc 框架代码。

构建

xmake

CO?推荐使用?xmake?作为构建工具。

  • 编译器

  • 安装 xmake

    windows, mac 与 debian/ubuntu 可以直接去 xmake 的?release?页面下载安装包,其他系统请参考 xmake 的?Installation?说明。

    xmake 在 linux 上默认禁止 root 用户编译,ruki?说不安全,可以在?~/.bashrc?中加上下面的一行,启用 root 编译:

    export?XMAKE_ROOT=y
  • 快速上手

    #?所有命令都在?co?根目录执行,后面不再说明
    xmake???????#?默认构建?libco?与?gen
    xmake?-a????#?构建所有项目?(libco,?gen,?co/test,?co/unitest)
  • 构建 libco

    xmake?build?libco???????#?仅构建?libco
    xmake?-b?libco??????????#?与上同
  • 构建及运行 unitest 代码

    co/unitest?是单元测试代码,用于检验 libco 库功能的正确性。

    xmake?build?unitest?????#?build?可以简写为?-b
    xmake?run?unitest?-a????#?执行所有单元测试
    xmake?r?unitest?-a??????#?同上
    xmake?r?unitest?-os?????#?执行单元测试?os
    xmake?r?unitest?-json???#?执行单元测试?json
  • 构建及运行 test 代码

    co/test?包含了一些测试代码。co/test 目录或子目录下增加?xxx.cc?源文件,然后在 co 根目录下执行?xmake build xxx?即可构建。

    xmake?build?flag?????????????#?编译?flag.cc
    xmake?build?log??????????????#?编译?log.cc
    xmake?build?json?????????????#?编译?json.cc
    xmake?build?rpc??????????????#?编译?rpc.cc
    xmake?build?easy?????????????#?编译?so/easy.cc
    xmake?r?flag?-xz?????????????#?测试?co/flag
    xmake?r?log??????????????????#?测试?co/log
    xmake?r?log?-cout????????????#?终端也打印日志
    xmake?r?log?-perf????????????#?log?库性能测试
    xmake?r?json?????????????????#?测试?json
    xmake?r?rpc??????????????????#?启动?rpc?server
    xmake?r?rpc?-c???????????????#?启动?rpc?client
    xmake?r?easy?-d?xxx??????????#?启动?web?server
  • 构建 gen

    #?建议将?gen?放到系统目录下(如?/usr/local/bin/).
    xmake?build?gen
    cp?gen?/usr/local/bin/
    gen?hello_world.proto

    proto?文件格式可以参考?hello_world.proto

  • 安装

    #?默认安装头文件、libco、gen
    xmake?install?-o?pkg??????????#?打包安装到?pkg?目录
    xmake?i?-o?pkg????????????????#?同上
    xmake?install?-o?/usr/local???#?安装到?/usr/local?目录

cmake

izhengfan?帮忙提供了 cmake 支持:

  • 默认只编译?libco?与?gen.

  • 编译生成的库文件在 build/lib 目录下,可执行文件在 build/bin 目录下.

  • 可以用?BUILD_ALL?指定编译所有项目.

  • 可以用?CMAKE_INSTALL_PREFIX?指定安装目录.

    mkdir?build?&&?cd?build
    cmake?..
    cmake?..?-DBUILD_ALL=ON?-DCMAKE_INSTALL_PREFIX=pkg
    make?-j8
    make?install


C++ 基础库 co v2.0 正式发布(协程库,日志库,JSON,网络编程...)

原文:https://blog.51cto.com/u_15236879/2832009

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!