1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/idealvin-coost

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
readme.md 21 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 27.11.2024 18:23 9bf4b61

Coost

Английский | 简体中文

Linux Build

Windows Build

Mac Build

Release

License: MIT

Небольшая библиотека для ускорения разработки на C++11.

0. Введение

Coost — элегантная и эффективная кроссплатформенная базовая библиотека C++. Её цель — создать инструмент, который сделает разработку на C++ простой и приятной.

Coost, или co для краткости, похожа на boost, но более легковесна. Статическая библиотека, созданная на Linux или Mac, имеет размер всего около 1 МБ. Тем не менее она предоставляет достаточно мощные функции:

Парсер командной строки и конфигурационного файла (flag) Библиотека высокопроизводительного логирования (log)
Фреймворк модульного тестирования Фреймворк бенчмаркинга
Go-style сопрограммы Сопрограммная сетевая библиотека
JSON RPC фреймворк Атомарные операции (atomic)

| Эффективный поток (fastream) | Эффективная строка (fastring) | | Строковые утилиты (str) | Библиотека времени (time) | | Библиотека потоков (thread) | Планировщик задач с таймером |

| Ориентированное на классы программирование | Эффективная библиотека JSON | | Хеш-библиотека | Библиотека путей | | Файловые утилиты (fs) | Системные операции (os) | | Быстрый распределитель памяти |

1. Спонсорство

Coost нуждается в вашей помощи. Если вы используете её или она вам нравится, вы можете стать спонсором. Большое спасибо!

— Github Sponsors

— A cup of coffee

2. Документация

3. Основные функции

3.0 Ориентированное на классы программирование

co/god.h предоставляет некоторые функции, основанные на шаблонах.

#include "co/god.h"

void f() {
    god::bless_no_bugs();
    god::is_same<T, int, bool>(); // T is int or bool?
}

3.1 flag

Flag — это парсер командной строки и файла конфигурации. Он похож на gflags, но более мощный:

  • Поддержка параметров из командной строки и из файла конфигурации.
  • Автоматическое создание файла конфигурации.
  • Поддержка псевдонимов флагов.
  • Флаги целочисленного типа, значение может иметь единицу измерения k, m, g, t, p.
#include "co/flag.h"
#include "co/cout.h"

DEF_bool(x, false, "x");
DEF_bool(y, true, "y");
DEF_bool(debug, false, "dbg", d);
DEF_uint32(u, 0, "xxx");
DEF_string(s, "", "xx");

int main(int argc, char** argv) {
    flag::parse(argc, argv);
    cout << "x: " << FLG_x << '\n';
    cout << "y: " << FLG_y << '\n';
    cout << "debug: " << FLG_debug << '\n';
    cout << "u: " << FLG_u << '\n';
    cout << FLG_s << "|" << FLG_s.size() << '\n';
    return 0;
}

В приведённом выше примере макросы, начинающиеся с DEF_, определяют 4 флага. Каждый флаг соответствует глобальной переменной, имя которой FLG_ плюс имя флага. Флаг debug имеет псевдоним d. После сборки приведённый выше код можно запустить следующим образом:

./xx                  # Run with default configs
./xx -x -s good       # x -> true, s -> "good"
./xx -debug           # debug -> true
./xx -xd              # x -> true, debug -> true
./xx -u 8k ### u -> 8192

./xx -mkconf          # Автоматически создать конфигурационный файл: xx.conf
./xx xx.conf          # запустить с конфигурационным файлом
./xx -conf xx.conf    # То же, что и выше

3.2 log

log — это высокопроизводительная библиотека журналов, некоторые компоненты в coost используют её для печати журналов.

log поддерживает два типа журналов: один — журнал уровня, который делится на 5 уровней: отладка, информация, предупреждение, ошибка и фатальный, печать фатального журнала приведёт к завершению программы; другой — тематический журнал, журналы группируются по темам, а журналы разных тем записываются в разные файлы.

#include "co/log.h"

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

    TLOG("xx") << "s" << 23; // тематический журнал
    DLOG << "hello " << 23;  // отладка
    LOG << "hello " << 23;   // информация
    WLOG << "hello " << 23;  // предупреждение
    ELOG << "hello " << 23;  // ошибка
    FLOG << "hello " << 23;  // фатальный

    return 0;
}

co/log также предоставляет ряд макросов CHECK, которые являются улучшенной версией assert, и они не будут очищены в режиме отладки.

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

log работает очень быстро, вот некоторые результаты тестов:

платформа glog co/log speedup
win2012 HHD 1,6 МБ/с 180 МБ/с 112,5
win10 SSD 3,7 МБ/с 560 МБ/с 151,3
mac SSD 17 МБ/с 450 МБ/с 26,4
linux SSD 54 МБ/с 1023 МБ/с 18,9

Выше приведена скорость записи co/log и glog (один поток, 1 миллион журналов). Видно, что co/log почти на два порядка быстрее, чем glog.

потоки linux co/log linux spdlog win co/log win spdlog speedup
1 0,087235 2,076172 0,117704 0,461156 23,8/3,9
2 0,183160 3,729386 0,158122 0,511769 20,3/3,2
4 0,206712 4,764238 0,316607 0,743227 23,0/2,3
8 0,302088 3,963644 0,406025 1,417387 13,1/3,5

Приведённое выше время печати 1 миллиона журналов с 1, 2, 4 и 8 потоками, в секундах. Speedup — это улучшение производительности co/log по сравнению с spdlog на платформах Linux и Windows.

3.3 unitest

unitest — это простой и удобный в использовании фреймворк модульного тестирования. Многие компоненты в coost используют его для написания кода модульных тестов, что гарантирует стабильность coost.

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

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

    DEF_case(cpunum) {
        EXPECT_GT(os::cpunum(), 0);
    }
}
 
int main(int argc, char** argv) {
    flag::parse(argc, argv);
    unitest::run_tests();
    return 0;
}

Приведенный выше пример является простым примером. Макрос DEF_test определяет тестовый модуль, который фактически является функцией (методом класса). Макрос DEF_case определяет тестовые случаи, и каждый тестовый случай фактически представляет собой блок кода.

В каталоге unitest находится код модульных тестов в coost. Пользователи могут запускать unitest с помощью следующих команд:

xmake r unitest      # Запустить все тестовые примеры
xmake r unitest -os  # Запустить тестовые примеры в модуле os

3.4 JSON

В coost v3.0 Json предоставляет fluent API, что более удобно в использовании.

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

// equal to x
co::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**
os co/json stringify co/json parse rapidjson stringify rapidjson parse speedup
win 569 924 2089 2495 3.6/2.7
mac 783 1097 1289 1658 1.6/1.5
linux 468 764 1359 1070 2.9/1.4

The above is the average time of stringifying and parsing minimized twitter.json, in microseconds (us), speedup is the performance improvement of co/json compared to rapidjson.

3.5 Coroutine

coost has implemented a go-style coroutine, which has the following features:

  • Поддержка многопоточного планирования, по умолчанию количество потоков равно количеству системных ядер процессора.
  • Общий стек, сопрограммы в одном потоке используют несколько стеков (размер по умолчанию — 1 МБ), что снижает использование памяти.
  • Существует плоская связь между сопрограммами, и новые сопрограммы могут быть созданы из любого места (включая другие сопрограммы).
  • Поддержка событий синхронизации сопрограмм, блокировок сопрограмм, каналов и групп ожидания.
#include "co/co.h"

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

    co::wait_group wg;
    wg.add(2);

    go([wg](){
        LOG << "hello world";
        wg.done();
    });

    go([wg](){
        LOG << "hello again";
        wg.done();
    });

    wg.wait();
    return 0;
}

В приведённом выше коде сопрограммы, созданные с помощью go(), будут распределены по различным планирующим потокам. Пользователи также могут самостоятельно контролировать планирование сопрограмм:

// запустить f1 и f2 в одном планировщике
auto s = co::next_sched();
s->go(f1);
s->go(f2);

// запустить f во всех планировщиках
for (auto& s : co::scheds()) {
    s->go(f);
}

3.6 Сетевое программирование

coost предоставляет основанную на сопрограммах структуру сетевого программирования:

  • Сопрограммированный API сокетов, похожий по форме на системный API сокетов, пользователи, знакомые с программированием сокетов, могут легко писать высокопроизводительные сетевые программы синхронным способом.
  • TCP, HTTP, RPC и другие высокоуровневые компоненты сетевого программирования, совместимые с IPv6, также поддерживают SSL, их проще использовать, чем API сокетов.

Сервер RPC

#include "co/co.h"
#include "co/rpc.h"
#include "co/time.h"

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

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

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

rpc::Server также поддерживает протокол HTTP, вы можете использовать метод POST для вызова службы RPC:

curl http://127.0.0.1:7788/xx --request POST --data '{"api":"ping"}'

Статический веб-сервер

#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::parse(argc, argv);
    so::easy(FLG_d.c_str()); // mum never have to worry again
    return 0;
}

HTTP-сервер

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

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();
``` **Код композиции**

- include  заголовочные файлы coost.
- src  исходные файлы coost, собранные как libco.
- test  тестовый код, каждый файл .cc будет скомпилирован в отдельную тестовую программу.
- unitest  код модульного теста, каждый файл .cc соответствует отдельному тестовому блоку, и весь код будет скомпилирован в одну тестовую программу.
- gen  генератор кода для RPC-фреймворка.

**Сборка**

5.1. Необходимые компиляторы

Для сборки coost нужен компилятор, поддерживающий C++11:

* Linux: gcc 4.8+.
* Mac: clang 3.3+.
* Windows: vs2015+.

5.2. Сборка с помощью xmake

coost рекомендует использовать xmake в качестве инструмента сборки.

5.2.1 Быстрый старт

```sh
# Все команды выполняются в корневом каталоге coost (то же самое ниже)
xmake      # по умолчанию сборка libco
xmake -a   # сборка всех проектов (libco, gen, test, unitest)

5.2.2 Сборка разделяемой библиотеки

xmake f -k shared
xmake -v

5.2.3 Сборка с mingw

xmake f -p mingw
xmake -v

5.2.4 Включение функций HTTP/SSL

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

5.2.5 Установка libco

# По умолчанию устанавливаются файлы заголовков и libco.
xmake install -o pkg         # упаковать связанные файлы в каталог pkg
xmake i -o pkg               # то же, что и выше
xmake install -o /usr/local  # установить в каталог /usr/local

5.2.6 Установка libco из xrepo

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

5.3. Сборка с cmake

izhengfan помог предоставить поддержку cmake, SpaceIm улучшил её и довёл до совершенства.

5.3.1 Сборка libco

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

5.3.2 Сборка всех проектов

mkdir build && cd build
cmake .. -DBUILD_ALL=ON
make -j8

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 Поиск coost в Cmake

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

5.3.6 vcpkg & conan

vcpkg install coost:x64-windows

# Поддержка HTTP & SSL
vcpkg install coost[libcurl,openssl]:x64-windows

conan install coost
  1. Лицензия

Лицензия MIT. coost содержит коды из некоторых других проектов, которые имеют собственные лицензии, подробности см. в LICENSE.md.

  1. Особые благодарности

— Код co/context взят из tbox от ruki, особая благодарность! — Ранние английские документы co переведены Leedehai и daidai21, особая благодарность! — ruki помог улучшить сценарии сборки xmake, спасибо! — izhengfan предоставил сценарии сборки cmake, большое спасибо! — SpaceIm улучшил сценарии сборки cmake и предоставил поддержку find_package. Действительно большая помощь, спасибо!

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/idealvin-coost.git
git@api.gitlife.ru:oschina-mirror/idealvin-coost.git
oschina-mirror
idealvin-coost
idealvin-coost
master