async_simple:一个轻量级C++异步协程框架

目录

1.简介

2.安装与集成

2.1.核心依赖

[2.2.安装 async_simple](#2.2.安装 async_simple)

[2.3.项目集成(CMake 示例)](#2.3.项目集成(CMake 示例))

3.核心组件

4.快速上手示例

5.适用场景

6.与其他异步库对比

7.注意事项

8.总结


1.简介

async_simple 是 一个开源的轻量级 C++ 异步编程库 ,核心目标是为 C++ 开发者提供简单、高效、低开销的异步编程能力,同时兼容 C++11+ 标准(无需等待 C++20 协程),并支持多种执行模型(协程、线程池、异步 IO 等)。提供‌Lazy(无栈协程)、Uthread(有栈协程)和‌Future/‌Promise三种异步编程模型,广泛应用于高性能计算场景。‌‌

它的设计理念是「简单易用、零侵入、高性能」,解决了传统异步编程(回调地狱)、Boost.Asio 等库的复杂度问题,同时保持了接近原生代码的性能。

核心特性:

1.多协程模型支持

  • 无栈协程(Lazy):轻量级协程,无独立栈空间,内存开销极低(仅需保存上下文),适合 IO 密集型场景(如网络请求、数据库操作)。
  • 有栈协程(Uthread):拥有独立栈空间,兼容需要栈操作的场景(如第三方库调用),性能接近线程但开销更低。
  • C++20 协程兼容 :可无缝对接 C++20 std::coroutine_traits,支持 co_await/co_return 语法(需编译器支持 C++20)。

2.轻量级 Task 模型

  • 异步任务载体 Task<T>/Lazy<T>,支持链式调用(then/map/flat_map),避免回调地狱。
  • 支持任务取消(Cancellation)、异常传播(Exception Propagation),语义清晰。

3.灵活的执行器(Executor)

  • 内置多种执行器:
    • 单线程执行器(SingleThreadExecutor):适用于串行任务。
    • 线程池执行器(ThreadPoolExecutor):适用于并行任务,支持动态调整线程数。
    • 协程执行器(CoroutineExecutor):专门调度协程任务,优化上下文切换。
  • 支持自定义执行器:可对接用户自己的线程池或调度器。

4.异步同步原语

  • 提供异步安全的同步工具,避免阻塞线程:
    • AsyncMutex/AsyncRWMutex:异步互斥锁,co_await lock() 不会阻塞线程。
    • AsyncConditionVariable:异步条件变量,支持 co_await wait()
    • CountDownLatch/Semaphore:异步计数器、信号量。

5.兼容性与无侵入性

  • 兼容 C++11+,无需依赖 Boost 等重型库,编译体积小。
  • 可与现有同步代码无缝衔接:同步函数可通过 syncAwait 转为异步调用,异步任务可通过 blockOn 阻塞等待结果。

6.高性能

  • 无栈协程上下文切换开销接近 0(仅保存寄存器状态)。
  • 任务调度无额外开销,执行器采用无锁设计,支持批量任务提交。
  • 内存占用低:无栈协程仅需几十字节,线程池支持空闲线程回收。

2.安装与集成

2.1.核心依赖

async_simple 无第三方依赖,仅需满足以下基础环境:

依赖项 最低版本要求 说明
编译器 GCC 7+ / Clang 6+ / MSVC 19.20+ 需支持 C++11+(推荐 C++17 以获得更好体验)
CMake 3.10+ 构建工具
可选依赖 C++20 编译器支持 若需使用 C++20 协程(如 Task<T> 原生 co_await

2.2.安装 async_simple

async_simple 支持两种安装方式:源码编译安装 (推荐,灵活可控)和 包管理器安装(仅部分系统支持)。

方式 1:源码编译安装(跨平台通用)

这是最稳定的安装方式,支持自定义编译选项(如静态库 / 动态库、C++20 支持等)。

步骤 1:克隆源码

https://github.com/alibaba/async_simple

cpp 复制代码
# 克隆仓库(推荐指定版本标签,避免开发分支变动)
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
  • --branch v0.10.0:指定版本(可在 GitHub Releases 查看最新版本)。
  • --depth 1:仅克隆最新提交,减少下载体积。

步骤 2:配置 CMake

创建构建目录并配置编译选项:

cpp 复制代码
mkdir build && cd build

# 基础配置(默认静态库、关闭测试、C++17)
cmake .. \
  -DCMAKE_BUILD_TYPE=Release \          # 构建类型:Release(优化)/ Debug(调试)
  -DASYNC_SIMPLE_BUILD_TEST=OFF \       # 不编译测试(加快编译速度)
  -DASYNC_SIMPLE_BUILD_EXAMPLES=OFF \   # 不编译示例
  -DCMAKE_INSTALL_PREFIX=/usr/local \   # 安装路径(默认 /usr/local,可自定义)
  -DCMAKE_CXX_STANDARD=17               # 指定 C++ 标准(11/14/17/20)

可选编译选项(按需添加)

选项 作用 取值
BUILD_SHARED_LIBS 编译动态库(.so/.dll)而非静态库 ON/OFF(默认 OFF)
ASYNC_SIMPLE_ENABLE_CPP20 启用 C++20 协程支持(需编译器支持) ON/OFF(默认 OFF)
ASYNC_SIMPLE_ENABLE_UTTHREAD 启用有栈协程(Uthread)支持 ON/OFF(默认 ON)
ASYNC_SIMPLE_BUILD_BENCHMARK 编译性能基准测试程序 ON/OFF(默认 OFF)
cpp 复制代码
cmake .. \
  -DCMAKE_BUILD_TYPE=Release \
  -DASYNC_SIMPLE_BUILD_TEST=OFF \
  -DCMAKE_CXX_STANDARD=20 \
  -DASYNC_SIMPLE_ENABLE_CPP20=ON \
  -DBUILD_SHARED_LIBS=ON \
  -DCMAKE_INSTALL_PREFIX=/usr/local

安装结果验证

安装完成后,/usr/local(或自定义路径)下会生成以下文件:

cpp 复制代码
/usr/local/
├── include/async_simple/  # 头文件
├── lib/                    # 库文件(.a 静态库 / .so 动态库)
└── lib/cmake/async_simple/ # CMake 配置文件(用于项目集成)

方式 2:包管理器安装(便捷但版本可能滞后)

Windows(vcpkg):

cpp 复制代码
vcpkg install async-simple

macOS(Homebrew):

cpp 复制代码
brew install async-simple

2.3.项目集成(CMake 示例)

async_simple 安装后,通过 CMake 可快速集成到你的项目中。以下是完整示例:

创建项目结构

cpp 复制代码
my_async_project/
├── CMakeLists.txt  # 项目配置文件
└── main.cpp        # 测试代码

编写 CMakeLists.txt

cpp 复制代码
# 指定 CMake 最低版本
cmake_minimum_required(VERSION 3.10)

# 项目名称与 C++ 标准
project(my_async_project)
set(CMAKE_CXX_STANDARD 17)  # 匹配安装时的 C++ 标准
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 查找 async_simple 库(自动找到头文件和库文件)
find_package(async_simple REQUIRED)

# 创建可执行文件
add_executable(my_async_app main.cpp)

# 链接 async_simple 库(静态库/动态库自动适配)
target_link_libraries(my_async_app PRIVATE async_simple::async_simple)

# (可选)若启用了 C++20 协程,添加编译器选项
if(CMAKE_CXX_STANDARD GREATER_EQUAL 20)
  if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
    target_compile_options(my_async_app PRIVATE -fcoroutines)
  elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
    target_compile_options(my_async_app PRIVATE -fcoroutines-ts)
  endif()
endif()

编写测试代码(main.cpp)

cpp 复制代码
#include <async_simple/coro/Lazy.h>
#include <async_simple/executor/SimpleExecutor.h>
#include <async_simple/syncAwait.h>
#include <iostream>

using namespace async_simple;
using namespace async_simple::coro;

// 异步任务:模拟 IO 操作
Lazy<int> asyncAdd(int a, int b) {
    co_await sleep(500);  // 异步睡眠 500ms(不阻塞线程)
    co_return a + b;
}

int main() {
    // 创建单线程执行器
    executor::SimpleExecutor ex(1);

    // 同步等待异步任务结果
    int result = syncAwait(asyncAdd(10, 20).via(&ex));

    std::cout << "10 + 20 = " << result << std::endl;  // 输出:10 + 20 = 30
    return 0;
}

编译运行项目

cpp 复制代码
# 创建构建目录
mkdir build && cd build

# 配置 CMake(若 async_simple 安装在非默认路径,需指定 CMAKE_PREFIX_PATH)
cmake .. 
# 若自定义安装路径(如 ~/local),需添加:
# cmake .. -DCMAKE_PREFIX_PATH=~/local

# 编译
make -j4

# 运行
./my_async_app

3.核心组件

组件 作用 适用场景
Lazy<T> 无栈协程任务(延迟执行,需 co_await IO 密集型、链式异步任务
Task<T> 可调度的异步任务(主动执行) 并行任务、需要线程池调度的场景
Executor 任务调度器 控制任务的执行线程 / 协程上下文
syncAwait 阻塞等待异步任务结果(同步转异步) 主线程等待异步任务
blockOn 协程内阻塞等待(不阻塞物理线程) 协程中调用同步函数
异步同步原语 协程间同步(无阻塞) 协程间资源竞争、协作

4.快速上手示例

示例 1:无栈协程(Lazy)链式调用

cpp 复制代码
#include <async_simple/coro/Lazy.h>
#include <async_simple/executor/SimpleExecutor.h>
#include <async_simple/syncAwait.h>
#include <iostream>

using namespace async_simple;
using namespace async_simple::coro;

// 异步任务1:模拟IO操作(延迟1s)
Lazy<int> asyncTask1() {
    co_await sleep(1000);  // 异步睡眠(不阻塞线程)
    co_return 42;          // 协程返回值
}

// 异步任务2:依赖任务1的结果
Lazy<std::string> asyncTask2(int val) {
    co_await sleep(500);
    co_return "Result: " + std::to_string(val * 2);
}

int main() {
    // 创建单线程执行器
    executor::SimpleExecutor ex(1);

    // 链式调用:task1 -> task2,通过 syncAwait 阻塞等待结果
    auto result = syncAwait(
        asyncTask1()
            .then([](int val) { return asyncTask2(val); })  // 链式调用
            .via(&ex)  // 指定执行器
    );

    std::cout << result << std::endl;  // 输出:Result: 84
    return 0;
}

示例 2:C++20 协程兼容(co_await)

cpp 复制代码
#include <async_simple/coro/Cpp20Coroutine.h>
#include <async_simple/executor/ThreadPoolExecutor.h>
#include <iostream>

using namespace async_simple;
using namespace async_simple::coro;

// C++20 协程任务(需编译器开启 -std=c++20)
Task<std::string> cpp20Task(ThreadPoolExecutor& ex) {
    // co_await 异步任务
    auto val = co_await Lazy<int>([]() -> Lazy<int> {
        co_await sleep(800);
        co_return 100;
    }).via(&ex);

    co_return "Cpp20 Coro Result: " + std::to_string(val);
}

int main() {
    ThreadPoolExecutor ex(4);  // 4线程池
    auto result = syncAwait(cpp20Task(ex));
    std::cout << result << std::endl;  // 输出:Cpp20 Coro Result: 100
    return 0;
}

示例 3:异步互斥锁(AsyncMutex)

cpp 复制代码
#include <async_simple/coro/Lazy.h>
#include <async_simple/sync/AsyncMutex.h>
#include <async_simple/executor/ThreadPoolExecutor.h>
#include <iostream>

using namespace async_simple;
using namespace async_simple::coro;
using namespace async_simple::sync;

AsyncMutex mutex;
int shared_val = 0;

Lazy<void> increment(ThreadPoolExecutor& ex) {
    // 异步加锁(不阻塞线程)
    auto guard = co_await mutex.lock();
    shared_val++;
    std::cout << "Shared val: " << shared_val << std::endl;
    // 自动解锁(guard 析构)
}

int main() {
    ThreadPoolExecutor ex(4);
    // 并行执行10个任务,通过 AsyncMutex 保证线程安全
    std::vector<Lazy<void>> tasks;
    for (int i = 0; i < 10; ++i) {
        tasks.emplace_back(increment(ex));
    }
    // 等待所有任务完成
    syncAwait(whenAll(std::move(tasks)));
    return 0;
}

5.适用场景

  1. IO 密集型应用:网络服务器(HTTP/RPC)、数据库客户端、文件 IO 等(无栈协程优势明显)。
  2. 高并发系统:需要大量并发任务但不想用线程(线程开销高)的场景(如百万级长连接服务)。
  3. 低延迟场景:协程上下文切换开销远低于线程,适合对延迟敏感的系统。
  4. 现有同步代码改造 :无需重写代码,通过 syncAwait/blockOn 快速接入异步模型。
  5. C++11+ 项目:无法使用 C++20 协程,但需要异步能力的旧项目。

6.与其他异步库对比

特性 async_simple Boost.Asio libuv C++20 std::coroutine
依赖 无(仅 C++11+) 依赖 Boost C 库(需 C++ 封装) C++20+
协程支持 无栈 / 有栈 / C++20 仅 C++20 无原生协程 仅 C++20 无栈
易用性 高(链式调用) 中(回调 / 协程) 低(C 风格回调) 中(需自定义执行器)
性能 高(无锁调度) 高(但功能有限)
同步原语 异步安全 异步安全 同步为主

核心优势async_simple 平衡了「易用性」和「性能」,无需依赖重型库,兼容旧标准,同时提供了完整的异步生态(协程、执行器、同步原语)。

7.注意事项

  1. 协程生命周期:无栈协程依赖执行器调度,需确保执行器生命周期长于协程任务。
  2. 异常处理 :异步任务的异常需通过 co_await 传播或 then 中捕获,避免未处理异常崩溃。
  3. C++20 兼容 :若使用 C++20 协程,需开启编译器选项(如 -std=c++20),并确保执行器支持 C++20 协程调度。
  4. 性能优化 :IO 密集型任务优先使用 Lazy(无栈协程),CPU 密集型任务优先使用 ThreadPoolExecutor

8.总结

如果需要开发高并发、低延迟的 C++ 异步应用,且希望避免复杂依赖,async_simple 是非常优秀的选择。

相关推荐
难以触及的高度2 小时前
Java for循环完全指南:从基础到高性能实践
java·开发语言
wadesir2 小时前
用Python实现ggplot2风格绘图(零基础入门Seaborn与Matplotlib美化技巧)
开发语言·python·matplotlib
hnlq2 小时前
基于dpdk的用户态协议栈的实现(三)—— TCP的三次握手实现
网络·网络协议·tcp/ip
油炸自行车2 小时前
【Qt】Qt Creator Debug模式提示“缺少 Windows CDB 调试器配套的扩展组件“”
开发语言·windows·qt
budingxiaomoli2 小时前
多线程(三)
java·开发语言
VBA63372 小时前
VBA之Excel应用第十节:用Union和Intersect方法获得单元格区域
开发语言·自然语言处理
klzdwydz2 小时前
注解与反射
java·开发语言
ULTRA??2 小时前
C语言简化版本开辟动态内存的万能MALLOC宏封装
c语言·开发语言
2401_861277553 小时前
func(int* num)的实现是*num=2或者int a=3,num=&a都可以吗
c语言·c++