目录
[2.2.安装 async_simple](#2.2.安装 async_simple)
[2.3.项目集成(CMake 示例)](#2.3.项目集成(CMake 示例))
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:克隆源码
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.适用场景
- IO 密集型应用:网络服务器(HTTP/RPC)、数据库客户端、文件 IO 等(无栈协程优势明显)。
- 高并发系统:需要大量并发任务但不想用线程(线程开销高)的场景(如百万级长连接服务)。
- 低延迟场景:协程上下文切换开销远低于线程,适合对延迟敏感的系统。
- 现有同步代码改造 :无需重写代码,通过
syncAwait/blockOn快速接入异步模型。 - 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.注意事项
- 协程生命周期:无栈协程依赖执行器调度,需确保执行器生命周期长于协程任务。
- 异常处理 :异步任务的异常需通过
co_await传播或then中捕获,避免未处理异常崩溃。 - C++20 兼容 :若使用 C++20 协程,需开启编译器选项(如
-std=c++20),并确保执行器支持 C++20 协程调度。 - 性能优化 :IO 密集型任务优先使用
Lazy(无栈协程),CPU 密集型任务优先使用ThreadPoolExecutor。
8.总结
如果需要开发高并发、低延迟的 C++ 异步应用,且希望避免复杂依赖,async_simple 是非常优秀的选择。