Skip to content

Latest commit

 

History

History
278 lines (210 loc) · 11.5 KB

README_CN.md

File metadata and controls

278 lines (210 loc) · 11.5 KB

async_simple

A Simple, Light-Weight Asynchronous C++ Framework

license language feature last commit

中文 | English

async_simple是阿里巴巴开源的轻量级C++异步框架。提供了基于C++20无栈协程(Lazy),有栈协程(Uthread)以及Future/Promise等异步组件。async_simple诞生于阿里巴巴智能引擎事业部,目前广泛应用于图计算引擎、时序数据库、搜索引擎等在线系统。连续两年经历天猫双十一磨砺,承担了亿级别流量洪峰,具备非常强劲的性能和可靠的稳定性。

快速体验

我们可以在 compiler-explorer 中在线快速体验 async_simple: https://compiler-explorer.com/z/Tdaesqsqj . 注意 Uthread 在 compiler-explorer 中不能使用。

快速入门

我们的文档托管在GitHub Pages上,点击进入快速开始.

接下来可以阅读更多API文档,例如C++20协程(Lazy)。熟悉async_simple组件,可以先跟着Demo用C++20协程来实现异步统计文件字符数功能。

更多文档介绍见目录docs

安装async_simple

使用vcpkg安装

./vcpkg install async-simple

使用cmake安装

git clone -b main --single-branch --depth 1 https://github.com/alibaba/async_simple.git
cd async_simple
mkdir build
cd build
cmake .. -DASYNC_SIMPLE_ENABLE_TESTS=OFF -DASYNC_SIMPLE_BUILD_DEMO_EXAMPLE=OFF -DASYNC_SIMPLE_ENABLE_ASAN=OFF
cmake --build .
cmake --install . # --prefix ./user_defined_install_path 

导入

当你安装完async_simple以后,你可以在你的项目里导入async_simple。

通过cmake find_package

请在项目中添加以下cmake代码:

find_package(async_simple REQUIRED)
target_link_libraries(<your-target-name> PRIVATE async_simple::async_simple) # dynamic_link
                                 # async_simple::async_simple_header_only   
                                 # async_simple::async_simple_static  

其中,<your-target-name> 是你需要使用async_simple的target名

手动导入

async_simple几乎是header-only的. 因此你只需要将安装的include路径传递给编译器即可。

但是async_simple的uthread模块不是header-only的,如果你要使用uthread,我们在安装路径下生成了编译好的库文件,你需要手动链接它。

编译器约束

async_simple 涉及 C++20 协程,对编译器版本有较高要求。需要 clang10 或 gcc10 或 Apple-clang14 及其以上版本。

注意当使用 gcc12 时需要加上 -Wno-maybe-uninitialized 选项因为 gcc12 的一个误报。详情可见 https://github.com/alibaba/async_simple/issues/234。

若你需要使用 async_simple::Generator,我们推荐使用 clang17 或更高的版本因为在低版本 clang 上存在一些关于 Generator 的 bug report。

注意,如果使用msvc时遇到了C4737错误,请加上选项/EHa。

开发async_simple

本项目编译运行测试需要 gtest和gmock,需要 libaio 的示例代码则依赖 libaio。

默认情况下,async_simple 会尝试从 git 拉取 gtest 源码以保证版本一致性。在用户存在网络的情况下, 建议用户按照以下指令安装对应版本的 gtest 并使用 CMake 变量 ('GMOCK_INCLUDE_DIR', 'GTEST_LIBRARIES', 'GMOCK_INCLUDE_DIR', 'GMOCK_LIBRARIES') 指定安装的 gtest 所在的位置。

Debian/Ubuntu系列

  • 安装clang11及其以上版本。安装方法见:APT Packages
  • 安装cmake或bazel
  • 如需使用 libaio 功能,需安装 libaio。
sudo apt install libaio-dev -y
# Install cmake
sudo apt install cmake -y
# Install bazel See: https://bazel.build/install/ubuntu
  • 使用apt安装gtest、gmock
sudo apt install -y libgtest-dev libgmock-dev

CentOS/Fedora系列

  • 同样是先安装clang11及其以上版本。安装方法见:Fedora Snapshot Packages
  • 安装cmake或bazel、libaio(可选)。
# Optional.
sudo yum install cmake libaio-devel -y
# Install bazel See: https://bazel.build/install/redhat
  • 使用yum安装gtest、gmock
sudo yum install gtest-devel gmock-devel
git clone [email protected]:google/googletest.git -b v1.8.x
cd googletest
mkdir build && cd build
cmake .. && sudo make install

Arch系列

# Optional
sudo pacman -S libaio
# Use cmake
sudo pacman -S cmake gtest
# Use bazel
sudo pacman -S bazel

macOS

  • 建议升级macOS 12.1,默认已安装clang13。
  • 安装cmake或者bazel,googletest。
# Use cmake
brew install cmake
brew install googletest
# Use bazel
brew install bazel

Windows

# Install cmake
winget install cmake
# Install google-test
# TODO
# Install bazel See: https://bazel.build/install/windows

源码依赖

  • 如果你不是上述Linux发行版,可以直接源码编译来安装依赖组件。
# libaio (optional)
git clone https://pagure.io/libaio.git
cd libaio
sudo make install
# gmock/gtest
git clone [email protected]:google/googletest.git -b v1.8.x
cd googletest
mkdir build && cd build
cmake .. && sudo make install

编译运行

  • 准备好编译器和依赖组件后就可以开始编译运行async_simple。
  • 首先克隆async_simple代码并进入代码目录,然后执行如下命令编译。
  • 编译成功结束后,运行单元测试以确保能够正常运行。

cmake

mkdir build && cd build
# Specify [-DASYNC_SIMPLE_ENABLE_TESTS=OFF] to skip tests.
# Specify [-DASYNC_SIMPLE_BUILD_DEMO_EXAMPLE=OFF] to skip build demo example.
# Specify [-DASYNC_SIMPLE_DISABLE_AIO=ON] to skip the build libaio
CXX=clang++ CC=clang cmake ../ -DCMAKE_BUILD_TYPE=[Release|Debug] [-DASYNC_SIMPLE_ENABLE_TESTS=OFF] [-DASYNC_SIMPLE_BUILD_DEMO_EXAMPLE=OFF] [-DASYNC_SIMPLE_DISABLE_AIO=ON] [-DGMOCK_INCLUDE_DIR=<path-to-headers of gtest> -DGTEST_INCLUDE_DIR=<path-to-headers of mock> -DGTEST_LIBRARIES=<path-to-library-of-gtest>  -DGMOCK_LIBRARIES=<path-to-library-of-gmock> ]
make -j4
make test
make install

我们也支持了conan,你可以将async_simple安装到conan到本地缓存中。

mkdir build && cd build
conan create ..

bazel

# Specify [--define=ASYNC_SIMPLE_DISABLE_AIO=true] to skip the build libaio
# Example bazel build --define=ASYNC_SIMPLE_DISABLE_AIO=true ...
bazel build ...                     # compile all target
bazel build ...:all                 # compile all target
bazel build ...:*                   # compile all target
bazel build -- ... -benchmarks/...  # compile all target except those beneath `benchmarks`
bazel test ...                      # compile and execute tests
# Specify compile a target
# Format: bazel [build|test|run] [directory name]:[binary name]
# Example
bazel build :async_simple           # only compile libasync_simple
bazel run benchmarks:benchmarking   # compile and run benchmark
bazel test async_simple/coro/test:async_simple_coro_test
# Use clang toolchain
bazel build --action_env=CXX=clang++ --action_env=CC=clang ...
# Add compile option 
bazel build --copt='-O0' --copt='-ggdb' ...
  • 这里获得bazel build的更多信息
  • ...表示递归扫描所有目标,在oh-my-zsh中被识别为../..,可更换其他shell或使用bash -c 'command.'运行,例如bash -c 'bazel build ...', 或者使用bazel build ...:all
  • 使用async_simple作为第三方依赖库,也可以看看bazel support

Docker 编译环境

git clone https://github.com/alibaba/async_simple.git
cd async_simple/docker/(ubuntu|centos7|rockylinux)
docker build . --no-cache -t async_simple:1.0
docker run -it --name async_simple async_simple:1.0 /bin/bash

性能相关

关于基于C++20无栈协程(Lazy)和有栈协程(Uthread)的性能定量分析,详见定量分析报告

C++20 Modules

我们在 modules/async_simple.cppm 中对 C++20 Modules 做了实验性质的支持。async_simple Module 可被 xmakecmake 编译。我们可以在 CountChar, ReadFiles, LazyTest.cpp 以及 FutureTest.cpp 中找到相关的使用方法。

我们需要 clang16 (或 commit 号大于 d18806e6733) 来构建 async_simple Module。该功能只在 libstdc++10.3 中测试过。鉴于目前 Modules 的支持状况,如果在其他版本的标准库中无法正常使用 async_simple Module 并不意外。

我们可以用 xmake (>= 0eccc6e) 来构建 async_simple Module:

xmake

我们可以用 cmake (>= d18806e673 或 cmake 3.26 及更高版本)来构建 async_simple Module:

mkdir build_modules && cd build_modules
CC=clang CXX=clang++ cmake .. -DCMAKE_BUILD_TYPE=Release -DASYNC_SIMPLE_BUILD_MODULES=ON -GNinja
ninja

若 std module 在环境中可用,我们可以在配置 cmake 时定义 -DSTD_MODULE_AVAILABLE=ON 以使用官方的 std module。

需要注意: 出于兼容性考虑,目前 main 分支中的 async_simple Module 本质上只是将 async_simple 的头文件封装为了 Named Modules 而已。我们可以在 https://github.com/alibaba/async_simple/tree/CXX20Modules 中找到更完整的 Named Modules 使用方式。该分支中同样包含 xmake 和 cmake 的支持。

存在问题?

如果在使用时遇到任何问题,我们建议先阅读 文档, issues 以及 discussions. 如果你没有找到满意的答案,可以提一个 Issue 或者在 discussions 中开启讨论。具体地,对于缺陷报告以及功能增强,我们建议提一个 Issue;而对于如何使用等问题,我们建议在 discussions 中开启讨论。

示例依赖

注意目前示例代码包含了单独asio代码。对应Commit: f70f65ae54351c209c3a24704624144bfe8e70a3

如何贡献

  • 提前阅读下文档:如何修复Issue
  • 确保修改后单元测试通过,代码格式化通过。(git-clang-format HEAD^)。目前 CI 系统中的 clang-format 版本为 14。当 CI 中提示的 format 结果不好时,也可考虑暂时先 accept 并在 clang-format 社区提交相关 issue。
  • 创建并提交Pull Request,选择开发者Review代码。(候选人:ChuanqiXu9, RainMark, foreverhy, qicosmos)
  • 最终意见一致后,代码将会被合并。

许可证

async_simple遵循Apache License (Version 2.0)开源许可证。async_simple包含的部分第三方组件可能遵循其它开源许可证。相关详细信息可以查看NOTICE文件。