1 Star 0 Fork 6

NathanJoy / coost

forked from Gitee 极速下载 / coost 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

Coost

English | 简体中文

Linux Build Windows Build Mac Build Release License: MIT

A tiny boost library in C++11.

0. Coost 简介

Coost 是一个优雅、高效的跨平台 C++ 基础库,它没有 boost 那么重,但仍然提供了足够强大的功能:

  • 命令行参数与配置文件解析库(flag)
  • 高性能日志库(log)
  • 单元测试框架(unitest)
  • go-style 协程
  • 基于协程的网络编程框架
  • 高效 JSON 库
  • 基于 JSON 的 RPC 框架
  • 面向玄学编程
  • 原子操作(atomic)
  • 随机数生成器(random)
  • 高效字符流(fastream)
  • 高效字符串(fastring)
  • 字符串操作(str)
  • 时间库(time)
  • 线程库(thread)
  • 定时任务调度器
  • 高效内存分配器
  • LruMap
  • hash 库
  • path 库
  • 文件系统操作(fs)
  • 系统操作(os)

Coost 原名 cocoyaxi(简称co),因担心暴露过多信息而使 Namake 星遭受黑暗森林打击,故改名为 Coost,意为比 boost 更加轻量级的 C++ 基础库。

传说在距离地球约xx光年的地方,有一颗名为娜美克(Namake)的行星,娜美克星有一大两小三个太阳。娜美克星人以编程为生,他们按编程水平将所有人分成九个等级,水平最低的三个等级会被送往其他星球发展编程技术。这些外派的娜美克星人,必须通过一个项目,集齐至少10000个赞,才能重返娜美克星。

若干年前,两个娜美克星人 rukialvin,被发配到地球上。为了早日回到娜美克星,ruki 开发了一个强大的构建工具 xmake,该名字就是取自 Namake。alvin 则开发了一个微型 boost 库 coost, 其原名 cocoyaxi 取自 ruki 和 alvin 在娜美克星上居住的可可亚西村。

1. 赞助

Coost 的发展离不开大家的帮助,如果您在使用或者喜欢 Coost,可以考虑赞助本项目,非常感谢🙏

特别赞助

Coost 由以下企业特别赞助,在此深表感谢🙏

2. 参考文档

3. 核心组件

3.0 面向玄学编程

#include "co/god.h"

void f() {
    god::bless_no_bugs();
}

3.1 co/flag

co/flag 是一个命令行参数与配置文件解析库,用法与 gflags 类似,但功能更加强大:

  • 支持从命令行、配置文件传入参数。
  • 支持自动生成配置文件。
  • 支持 flag 别名。
  • 整数类型的 flag,值可以带单位 k,m,g,t,p,不分大小写。
#include "co/flag.h"
#include "co/cout.h"

DEF_bool(x, false, "bool x");
DEF_int32(i, 0, "...");
DEF_string(s, "hello world", "string");

int main(int argc, char** argv) {
    flag::init(argc, argv);
    COUT << "x: " << FLG_x;
    COUT << "i: " << FLG_i;
    COUT << FLG_s << "|" << FLG_s.size();
    return 0;
}

上述代码中 DEF_ 开头的宏,定义了 3 个 flag,每个 flag 对应一个全局变量,变量名是 FLG_ 加 flag 名。上面的代码编译后,可以按下面的方式运行:

./xx                    # 按默认参数运行
./xx -x -s good         # x = true, s = "good"
./xx -i 4k -s "I'm ok"  # i = 4096, s = "I'm ok"

./xx -mkconf            # 自动生成配置文件 xx.conf
./xx xx.conf            # 从配置文件传入参数
./xx -conf xx.conf      # 与上同

3.2 co/log

co/log 是一个内存友好的高性能日志系统,程序运行稳定后,打印日志不需要分配内存。

co/log 支持两种类型的日志:一种是级别日志,将日志分为 debug, info, warning, error, fatal 5 个级别,打印 fatal 级别的日志会终止程序的运行;另一种是 TLOG,日志按 topic 分类,不同 topic 的日志写入不同的文件。

DLOG << "hello " << 23;  // debug
LOG << "hello " << 23;   // info
WLOG << "hello " << 23;  // warning
ELOG << "hello " << 23;  // error
FLOG << "hello " << 23;  // fatal
TLOG("xx") << "s" << 23; // topic log

co/log 还提供了一系列 CHECK 宏,可以视为加强版的 assert,它们在 debug 模式下也不会被清除。

void* p = malloc(32);
CHECK(p != NULL) << "malloc failed..";
CHECK_NE(p, NULL) << "malloc failed..";

CHECK 断言失败时,co/log 会打印函数调用栈信息,然后终止程序的运行。在 linux 与 macosx 上,需要安装 libbacktrace

stack

co/log 速度非常快,下面是一些测试结果,仅供参考:

  • co/log vs glog (single thread)

    platform 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
  • co/log vs spdlog (Linux)

    threads total logs co/log time(seconds) spdlog time(seconds)
    1 1000000 0.087235 2.076172
    2 1000000 0.183160 3.729386
    4 1000000 0.206712 4.764238
    8 1000000 0.302088 3.963644

3.3 co/unitest

co/unitest 是一个简单易用的单元测试框架,co 中的很多组件会用它写单元测试代码,为 co 的稳定性提供了保障。

#include "co/unitest.h"
#include "co/os.h"

namespace test {
    
DEF_test(os) {
    DEF_case(homedir) {
        EXPECT_NE(os::homedir(), "");
    }

    DEF_case(cpunum) {
        EXPECT_GT(os::cpunum(), 0);
    }
}
    
} // namespace test

上面是一个简单的例子,DEF_test 宏定义了一个测试单元,实际上就是一个函数(类中的方法)。DEF_case 宏定义了测试用例,每个测试用例实际上就是一个代码块。main 函数一般只需要下面几行:

#include "co/unitest.h"

int main(int argc, char** argv) {
    flag::init(argc, argv);
    unitest::run_all_tests();
    return 0;
}

unitest 目录下面是 co 中的单元测试代码,编译后可执行下述命令运行:

xmake r unitest      # 运行所有单元测试用例
xmake r unitest -os  # 仅运行 os 单元中的测试用例

3.4 JSON

co/json 是一个兼具性能与易用性的 JSON 库。

// {"a":23,"b":false,"s":"123","v":[1,2,3],"o":{"xx":0}}
Json x = {
    { "a", 23 },
    { "b", false },
    { "s", "123" },
    { "v", {1,2,3} },
    { "o", {
        {"xx", 0}
    }},
};

// equal to x
Json y = Json()
    .add_member("a", 23)
    .add_member("b", false)
    .add_member("s", "123")
    .add_member("v", Json().push_back(1).push_back(2).push_back(3))
    .add_member("o", Json().add_member("xx", 0));

x.get("a").as_int();       // 23
x.get("s").as_string();    // "123"
x.get("s").as_int();       // 123, string -> int
x.get("v", 0).as_int();    // 1
x.get("v", 2).as_int();    // 3
x.get("o", "xx").as_int(); // 0

x["a"] == 23;          // true
x["s"] == "123";       // true
x.get("o", "xx") != 0; // false
  • co/json vs rapidjson (Linux)

    parse stringify parse(minimal) stringify(minimal)
    rapidjson 1270 us 2106 us 1127 us 1358 us
    co/json 1005 us 920 us 788 us 470 us

3.5 协程

co 实现了类似 golang goroutine 的协程,它有如下特性:

  • 支持多线程调度,默认线程数为系统 CPU 核数。
  • 共享栈,同一线程中的协程共用若干个栈(大小默认为 1MB),内存占用低,Linux 上的测试显示 1000 万协程只用了 2.8G 内存(仅供参考)。
  • 各协程之间为平级关系,可以在任何地方(包括在协程中)创建新的协程。
  • 支持系统 API hook (Windows/Linux/Mac),可以直接在协程中使用三方网络库。
  • 支持协程锁 co::Mutex、协程同步事件 co::Event
  • 支持 golang 中的 channel、waitgroup 等特性:co::Chanco::WaitGroup
  • 支持协程池 co::Pool(无锁、无原子操作)。
#include "co/co.h"

int main(int argc, char** argv) {
    flag::init(argc, argv);

    go(ku);            // void ku();
    go(f, 7);          // void f(int);
    go(&T::g, &o);     // void T::g(); T o;
    go(&T::h, &o, 7);  // void T::h(int); T o;
    go([](){
        LOG << "hello go";
    });

    co::sleep(32); // sleep 32 ms
    return 0;
}

上面的代码中,go() 创建的协程会均匀的分配到不同的调度线程中。用户也可以自行控制协程的调度:

// run f1 and f2 in the same scheduler
auto s = co::next_scheduler();
s->go(f1);
s->go(f2);

// run f in all schedulers
for (auto& s : co::schedulers()) {
    s->go(f);
}

3.6 网络编程

co 提供了一套协程化的 socket API,它们大部分形式上与原生的 socket API 基本一致,熟悉 socket 编程的用户,可以轻松的用同步的方式写出高性能的网络程序。

co 也实现了更高层的网络编程组件,包括 TCPHTTP 以及基于 JSONRPC 框架,它们兼容 IPv6,同时支持 SSL,用起来比 socket API 更方便。

  • RPC server
int main(int argc, char** argv) {
    flag::init(argc, argv);

    rpc::Server()
        .add_service(new xx::HelloWorldImpl)
        .start("127.0.0.1", 7788, "/xx");

    for (;;) sleep::sec(80000);
    return 0;
}

co/rpc 同时支持 HTTP 协议,可以用 POST 方法调用 RPC 服务:

curl http://127.0.0.1:7788/xx --request POST --data '{"api":"ping"}'
  • 静态 web server
#include "co/flag.h"
#include "co/http.h"

DEF_string(d, ".", "root dir"); // docroot for the web server

int main(int argc, char** argv) {
    flag::init(argc, argv);
    so::easy(FLG_d.c_str()); // mum never have to worry again
    return 0;
}
  • HTTP server
void cb(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
    }
}

// http
http::Server().on_req(cb).start("0.0.0.0", 80);

// https
http::Server().on_req(cb).start(
    "0.0.0.0", 443, "privkey.pem", "certificate.pem"
);
  • HTTP client
void f() {
    http::Client c("https://github.com");

    c.get("/");
    LOG << "response code: "<< c.status();
    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.status();
}

go(f);

4. 代码构成

  • include

    co 的头文件。

  • src

    co 的源代码,编译生成 libco。

  • test

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

  • unitest

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

  • gen

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

5. 构建

5.1 编译器要求

编译 co 需要编译器支持 C++11:

5.2 用 xmake 构建

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

5.2.1 快速上手

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

5.2.2 基于 mingw 构建

xmake f -p mingw
xmake -v

5.2.3 启用 HTTP/SSL 特性

xmake f --with_libcurl=true --with_openssl=true
xmake -v

5.2.4 安装 libco

xmake install -o pkg          # 打包安装到 pkg 目录
xmake i -o pkg                # 同上
xmake install -o /usr/local   # 安装到 /usr/local 目录

5.2.5 从 xrepo 安装 libco

xrepo install -f "openssl=true,libcurl=true" coost

5.3 用 cmake 构建

izhengfan 帮忙提供了 cmake 支持,SpaceIm 进一步完善了 cmake 脚本。

5.3.1 构建 libco

mkdir build && cd build
cmake ..
make -j8

5.3.2 构建所有项目

mkdir build && cd build
cmake .. -DBUILD_ALL=ON -DCMAKE_INSTALL_PREFIX=/usr/local
make -j8
make install

5.3.3 启用 HTTP/SSL 特性

mkdir build && cd build
cmake .. -DWITH_LIBCURL=ON -DWITH_OPENSSL=ON
make -j8

5.3.4 构建动态库

cmake .. -DBUILD_SHARED_LIBS=ON
make -j8

5.3.5 从 vcpkg 安装 libco

vcpkg install coost:x64-windows

# 启用 HTTP & SSL
vcpkg install coost[libcurl,openssl]:x64-windows

5.3.6 从 conan 安装 libco

conan install coost

5.3.7 Cmake 中查找 coost 包

find_package(coost REQUIRED CONFIG)
target_link_libraries(userTarget coost::co)

6. License

The MIT license. Coost 包含了一些其他项目的代码,可能使用了不同的 License,详情见 LICENSE.md

7. 特别致谢

  • co/context 的相关代码取自 rukitbox,特别表示感谢!
  • Leedehaidaidai21 早期帮忙将 co 的中文参考文档翻译成英文,特别表示感谢!
  • ruki 帮忙改进了 xmake 构建脚本,特别表示感谢!
  • izhengfan 提供了 cmake 构建脚本,特别表示感谢!
  • SpaceIm 完善了 cmake 构建脚本,提供了 find_package 的支持,特别表示感谢!

空文件

简介

coost 是一个兼具性能与易用性的跨平台 C++ 基础库,原名为 co,后改为 cocoyaxi,前者过短,后者过长,取中庸之道,又改为 coost 展开 收起
C/C++
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
C/C++
1
https://gitee.com/nathanjoy/coost.git
git@gitee.com:nathanjoy/coost.git
nathanjoy
coost
coost
master

搜索帮助