co 是一个优雅、高效的 C++ 基础库,支持 Linux, Windows 与 Mac 平台,它包含协程库、网络库、日志库、命令行与配置文件解析库、单元测试框架、JSON 库等基本组件。
co 遵循极简的设计理念,提供的接口都尽可能简单明了,用户可以轻松上手。co 尽量避免过度封装,引入过多的概念,以减轻用户的学习负担,如 co 提供的协程化的 socket API,与原生 socket API 形式上基本一致,熟悉 socket 编程的用户,几乎不需要增加新的学习成本,就能轻松用这些 API 写出高性能的网络程序。
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?是基于协程的 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?<<?"hello?"?<<?23;?//?info DLOG?<<?"hello"?<<?23;?//?debug WLOG?<<?"hello"?<<?23;?//?warning ELOG?<<?"hello?again";?//?error
与 glog 的性能比较
log vs glog | google glog | co/log |
---|---|---|
win2012 HHD | 1.6MB/s | 180MB/s |
win10 SSD | 3.7MB/s | 560MB/s |
mac SSD | 17MB/s | 450MB/s |
linux SSD | 54MB/s | 1023MB/s |
上表是单线程连续打印 100 万条 info 日志(每条 50 字节左右)的测试结果,co/log?几乎快了?glog?两个数量级。
为何如此快?一是 log 库内部基于比?sprintf
?快 8-25 倍的?fastream?实现,二是 log 库几乎没有什么内存分配操作。
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 的解析速度,可以达到 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
libco
?的头文件。
libco
?的源代码。
一些测试代码,每个?.cc
?文件都会编译成一个单独的测试程序。
一些单元测试代码,每个?.cc
?文件对应不同的测试单元,所有代码都会编译到单个测试程序中。
代码生成工具,根据 proto 文件,自动生成 rpc 框架代码。
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?目录
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