c#生成静态库_C++ 基础库 CO 1.2 发布 (协程库,日志库..)

github/idealvin/co

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.
  • 新增 lshift() 接口,将字符串左移若干字节.
fastring s = "hello"; 
s.lshift(2);  // s -> "llo"; 
s.lshift(8);  // s -> "";
  • 新增 shrink() 接口,与 std::stringshrink_to_fit() 类似,用于缩减 fastring 的容量.
fastring s(4096); // cap -> 4096 
s.shrink();       // cap < 4096

test/unitest

  • 去掉 test/unitest 代码文件名中的 _test 后缀.

下面是详细的介绍:

Basic

CO 是一个优雅、高效的 C++ 基础库,支持 Linux, Windows 与 Mac 平台。CO 追求极简、高效,不依赖于 boost 等三方库。

CO 包含协程库(golang-style)、网络库(tcp/http/rpc)、日志库、命令行与配置文件解析库、单元测试框架、json 库等基本组件。

参考文档

  • 中文
  • English

亮点功能

  • coco 是一个 golang 风格的 C++ 协程库,有如下特性:
    • 支持多线程调度,默认线程数为系统 CPU 核数.
    • 协程共享线程栈(默认大小为 1MB),内存占用极低,单机可轻松创建数百万协程.
    • 支持系统 api hook (Linux & Mac).
    • 支持协程锁 co::Mutex.
    • 支持协程同步事件 co::Event.
    • 支持协程池 co::Pool.
    • go() 创建协程:
void fun() {
    std::cout << "hello world" << std::endl;
}

go(fun);
  • soso 是基于协程的 C++ 网络库,可轻松实现同时支持 ipv4ipv6 的网络程序,包含如下几个模块:
    • tcp 模块, 支持一般的 tcp 编程.
    • http 模块, 支持基本的 http 编程.
    • rpc 模块,基于 json 的 rpc 框架,单线程 qps 可达到 12w+.
    • 实现静态 web server:
#include "co/flag.h"
#include "co/log.h"
#include "co/so.h"

DEF_string(d, ".", "root dir"); // Specify the root directory of the 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:
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();
  • loglog 是一个超级快的本地日志系统,打印日志比 printf 更安全:
LOG << "hello " << 23;  // info 
ELOG << "hello again";  // error


下面直观感受一下 log 的性能:

f2fe1333aff358a28dfa21d074676df7.png

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


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

  • flagflag 是一个方便、易用的命令行及配置文件解析库,支持自动生成配置文件。
#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          # 从配置文件启动
  • jsonjson 是一个速度堪比 rapidjson 的 json 库,如果使用 jemalloc,parsestringify 的性能会进一步提升。此库对 json 标准的支持不如 rapidjson 全面,但能满足程序员的基本需求,且更容易使用。

代码构成

  • co/includelibco 的头文件。
  • co/srclibco 的源代码。
  • co/test
    一些测试代码,每个 .cc 文件都会编译成一个单独的测试程序。
  • co/unitest
    一些单元测试代码,每个 .cc 文件对应不同的测试单元,所有代码都会编译到单个测试程序中。
  • co/gen
    代码生成工具,根据 proto 文件,自动生成 rpc 框架代码。

代码构成

  • co/includelibco 的头文件。
  • co/srclibco 的源代码。
  • co/test
    一些测试代码,每个 .cc 文件都会编译成一个单独的测试程序。
  • co/unitest
    一些单元测试代码,每个 .cc 文件对应不同的测试单元,所有代码都会编译到单个测试程序中。
  • co/gen
    代码生成工具,根据 proto 文件,自动生成 rpc 框架代码。

编译执行

xmake

CO 推荐使用 xmake 进行编译。

  • 编译器
    • Linux: gcc 4.8+
    • Mac: clang 3.3+
    • Windows: vs2015+
  • 安装 xmake
    windows, mac 与 debian/ubuntu 可以直接去 xmake 的 release 页面下载安装包,其他系统请参考 xmake 的 Installation 说明。xmake 在 linux 上默认禁止 root 用户编译,ruki 说不安全,可以在 ~/.bashrc 中加上下面的一行,启用 root 编译:
export XMAKE_ROOT=y
  • 快速上手
# 所有命令都在 co 根目录执行,后面不再说明 xmake       
xmake      # 默认编译 libco 与 gen xmake -a    
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_test.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
xmake build gen  # 建议将 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 支持:

  • 默认只编译 libcogen.
  • 编译生成的库文件在 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

COMIT License 发布. CO 包含了一些其他项目的代码,可能使用了与 CO 不同的 License,详情见 LICENSE.md。

特别致谢

  • co/context 的相关代码取自 ruki 的 tbox,特别表示感谢!
  • co 英文参考文档,由 Leedehai(1-10),daidai21(11-15) 与 google 翻译,特别表示感谢!
  • ruki 帮忙改进了 xmake 编译脚本,特别表示感谢!
  • izhengfan 提供了 cmake 编译脚本,特别表示感谢!
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
orchid是一个构建于强大的boost基础上的C ,类似于python下的gevent/eventlet,为用户提供基于协程的并发模型。 协程,顾名思义,协作式程序,其思想是,一系列互相依赖的协程间依次使用CPU,每次只有一个协程工作,而其他协程处于休眠状态。协程在控制离开时暂停执行,当控制再次进入时只能从离开的位置继续执行。 协程已经被证明是一种非常有用的程序组件,不仅被python、lua、ruby等脚本语言广泛采用,而且被新一代面向多核的编程语言如golang rust-lang等采用作为并发的基本单位。 协程可以被认为是一种用户空间线程,与传统的抢占式线程相比,有2个主要的优点: 与线程不同,协程是自己主动让出CPU,并交付他期望的下一个协程运行,而不是在任何时候都有可能被系统调度打断。因此协程的使用更加清晰易懂,并且多数情况下不需要锁机制。 与线程相比,协程的切换由程序控制,发生在用户空间而非内核空间,因此切换的代价非常的小。 green化 术语“green化”来自于python下著名的协程greenlet,指改造IO对象以能和协程配合。某种意义上,协程与线程的关系类似与线程与进程的关系,多个协程会在同一个线程的上下文之中运行。因此,当出现IO操作的时候,为了能够与协程相互配合,只阻塞当前协程而非整个线程,需要将io对象“green化”。目前orchid提供的green化的io对象包括: tcp socket(还不支持udp) descriptor(目前仅支持非文件类型文件描述符,如管道和标准输入/输出,文件类型的支持会在以后版本添加) timer (定时器) signal (信号) chan:协程间通信 chan这个概念引用自golang的chan。每个协程是一个独立的执行单元,为了能够方便协程之间的通信/同步,orchid提供了chan这种机制。chan本质上是一个阻塞消息队列,后面我们将看到,chan不仅可以用于同一个调度器上的协程之间的通信,而且可以用于不同调度器上的协程之间的通信。 多核 建议使用的scheduler per cpu的的模型来支持多核的机器,即为每个CPU核心分配一个调度器,有多少核心就创建多少个调度器。不同调度器的协程之间也可以通过chan来通信。协程应该被创建在哪个调度器里由用户自己决定。 进一步信息请阅读doc目录下tutorial。如果您发现任何bug或者有任何改进意见,请联系ioriiod0@gmail.com 标签:orchid
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值