Changes since v1.1
Bug 修复
- fix #77
- fix #83
- 修复协程库内部 Copool 未清空 Coroutine 中旧数据引起的 bug.
coroutine
- 重构协程库,简化内部逻辑
- 增加单元测试 unitest/co,用于测试 Scheduler 内部逻辑.
新增 http 模块
- 实现
http::Server 类.
- 实现
http::Client 类.
- 实现
so::easy(...) 接口,用于快速创建静态 web server.
hash
- 新增
size_t murmur_hash(...) 接口.
fastring
-
支持 std::hash<fastring>,std::unordered_map 可以使用 fastring 作为 key.
std::unordered_map<fastring, fastring> um;
LruMap<fastring, fastring> lm;
-
新增 lshift() 接口,将字符串左移若干字节.
fastring s = "hello";
s.lshift(2); // s -> "llo";
s.lshift(8); // s -> "";
-
新增 shrink() 接口,与 std::string 的 shrink_to_fit() 类似,用于缩减 fastring 的容量.
fastring s(4096); // cap -> 4096
s.shrink(); // cap < 4096
test/unitest
- 去掉 test/unitest 代码文件名中的
_test 后缀.
下面附上详细的介绍,以供参考:
CO 是一个优雅、高效的 C++ 基础库,支持 Linux, Windows 与 Mac 平台。CO 追求极简、高效,不依赖于 boost 等三方库。
CO 包含协程库(golang-style)、网络库(tcp/http/rpc)、日志库、命令行与配置文件解析库、单元测试框架、json 库等基本组件。
参考文档
亮点功能
-
co
co 是一个 golang 风格的 C++ 协程库,有如下特性:
void fun() {
std::cout << "hello world" << std::endl;
}
go(fun);
-
so
so 是基于协程的 C++ 网络库,可轻松实现同时支持 ipv4 与 ipv6 的网络程序,包含如下几个模块:
#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 serv("0.0.0.0", 80);
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(501);
}
}
);
serv.start();
-
log
log 是一个超级快的本地日志系统,打印日志比 printf 更安全:
LOG << "hello " << 23; // info
ELOG << "hello again"; // error
下面直观感受一下 log 的性能:
| 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
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.conf
./xx -config=xx.conf # 从配置文件启动
-
json
json 是一个速度堪比 rapidjson 的 json 库,如果使用 jemalloc,parse 与 stringify 的性能会进一步提升。此库对 json 标准的支持不如 rapidjson 全面,但能满足程序员的基本需求,且更容易使用。
代码构成
编译执行
xmake
CO 推荐使用 xmake 进行编译。
-
编译器
-
安装 xmake
windows, mac 与 debian/ubuntu 可以直接去 xmake 的 release 页面下载安装包,其他系统请参考 xmake 的 Installation 说明。
xmake 在 linux 上默认禁止 root 用户编译,ruki 说不安全,可以在 ~/.bashrc 中加上下面的一行,启用 root 编译:
-
快速上手
# 所有命令都在 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 rapidjson # 编译 rapidjson.cc
xmake build rpc # 编译 rpc.cc
xmake build easy # 编译 so/easy.cc
xmake build pingpong # 编译 so/pingpong.cc
xmake r flag -xz # 测试 flag 库
xmake r log # 测试 log 库
xmake r log -cout # 终端也打印日志
xmake r log -perf # log 库性能测试
xmake r json # 测试 json
xmake r rapidjson # 测试 rapidjson
xmake r rpc # 启动 rpc server
xmake r rpc -c # 启动 rpc client
xmake r easy -d xxx # 启动 web server
xmake r pingpong # pingpong server: 127.0.0.1:9988
xmake r pingpong ip=:: # pingpong server: :::9988 (ipv6)
xmake r pingpong -c ip=::1 # pingpong client -> ::1:9988
-
编译 gen
# 建议将 gen 放到系统目录下(如 /usr/local/bin/).
xmake build gen
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
License
CO 以 MIT License 发布. CO 包含了一些其他项目的代码,可能使用了与 CO 不同的 License,详情见 LICENSE.md。
特别致谢