{"id":13521152,"url":"https://github.com/archibate/co_async","last_synced_at":"2025-04-04T13:04:49.168Z","repository":{"id":228865688,"uuid":"775117840","full_name":"archibate/co_async","owner":"archibate","description":"C++20 Coroutine Library for Education Purpose (WIP)","archived":false,"fork":false,"pushed_at":"2025-03-10T06:30:30.000Z","size":2693,"stargazers_count":234,"open_issues_count":9,"forks_count":15,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-28T12:06:02.635Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/archibate.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-03-20T19:45:27.000Z","updated_at":"2025-03-27T01:42:05.000Z","dependencies_parsed_at":"2024-07-28T10:43:32.519Z","dependency_job_id":"e3e587df-d68c-479e-a93f-493413ec90f7","html_url":"https://github.com/archibate/co_async","commit_stats":null,"previous_names":["archibate/co_async"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/archibate%2Fco_async","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/archibate%2Fco_async/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/archibate%2Fco_async/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/archibate%2Fco_async/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/archibate","download_url":"https://codeload.github.com/archibate/co_async/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247182338,"owners_count":20897379,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T06:00:29.459Z","updated_at":"2025-04-04T13:04:49.136Z","avatar_url":"https://github.com/archibate.png","language":"C++","readme":"# co_async\n\n基于 C++20 协程的高并发异步 I/O 库（小彭老师教学用）\n\n## 特性\n\n- 100% 协程\n- HTTP \u0026amp; HTTPS 协议实现\n- [服务端](examples/server.cpp)和[客户端](examples/https_fetch.cpp)均有支持\n- 也支持[原始套接字](examples/echo_server.cpp)\n- 百万级并发\n- 纳秒级定时器\n- 支持 [WebSocket](examples/chat_server.cpp)\n- 也支持流式返回（SSE）\n- 支持[I/O 超时](examples/io_timeout.cpp)\n- 支持[任务取消](examples/cancel_test.cpp)\n- [创建进程并读写管道](examples/pipe_read.cpp)\n- 支持[用户态管道](examples/pipe_test.cpp)\n- [线程池执行阻塞任务](examples/blocking_test.cpp)\n- [条件变量](examples/condvar_test.cpp)\n- [异步队列](examples/queue_test.cpp)\n- 支持[inotify](examples/inotify.cpp)\n- 支持[futex](examples/futex_test.cpp)\n- 支持[多线程](examples/server_mt.cpp)\n- 可实现 [HTTP 转发](examples/proxy_server.cpp)\n- 自动识别 `http(s)_proxy` 代理\n- [文件服务器](examples/file_server.cpp)\n- [异步读写文件](examples/read_file.cpp)\n- [Expected](examples/expected.cpp) 语义\n- 更多新特性还在赶来中...\n\n## 教学视频\n\n- [第一集：C++20 协程概念初上手](https://www.bilibili.com/video/BV1Yz421Z7rZ)\n- [第二集：封装 epoll 实现 HTTP 客户端](https://www.bilibili.com/video/BV18t421G7fD)\n- [第三集：io uring 实现 HTTP 服务器](https://www.bilibili.com/video/BV1yD421H7KY)\n- [第四集：进一步完善 HTTP 路由，实现线程池](https://space.bilibili.com/263032155)（施工中，稍后上传）\n\n\u003e [steps 目录](steps) 是本库代码逐渐成形的过程，可以配合教学视频自己动手尝试。\n\n## 使用案例\n\n```cpp\n#include \u003cco_async/co_async.hpp\u003e\n\nusing namespace co_async;\nusing namespace std::literals;\n\nTask\u003cExpected\u003c\u003e\u003e amain() {\n    // 第一下 co_await 等待 bind 操作完成，返回一个 Expected\u003cT\u003e 对象。\n    // Expected\u003cT\u003e 有两种状态：1. 正常返回 T 值；2. 返回错误码 std::error_code\n    // 第二下 co_await 可以将 Expected\u003cT\u003e 的错误转化为当前函数的错误（没有错误则照常返回 T）：\n    auto listener = co_await co_await listener_bind({\"127.0.0.1\", 8080});\n    HTTPServer server;\n    server.route(\"GET\", \"/\", [](HTTPServer::IO \u0026io) -\u003e Task\u003cExpected\u003c\u003e\u003e {\n        HTTPResponse res = {\n            .status = 200,\n            .headers = {\n                {\"content-type\", \"text/html;charset=utf-8\"},\n            },\n        };\n        std::string_view body = \"\u003ch1\u003eIt works!\u003c/h1\u003e\";\n        co_await io.response(res, body);\n        co_return {};\n    });\n\n    while (true) {\n        if (auto income = co_await listener_accept(listener)) {\n            // 如果成功 accept 到输入连接，则开始处理 HTTP 请求\n            co_spawn(server.handle_http(std::move(*income)));\n        }\n    }\n}\n\nint main() {\n    co_main(amain());\n    return 0;\n}\n```\n\n\u003e [examples 目录](examples) 中有更多案例。多线程版本详见 [examples/server_mt.cpp](examples/server_mt.cpp)\n\n## 平台要求\n\n### Linux\n\n- Linux 内核 \u003e= 5.19\n- GCC \u003e= 10\n- Clang \u003e= 16\n\n小彭老师推荐使用 Arch Linux 系统作为开发平台：\n\n```bash\ncmake -B build\ncmake --build build --parallel 8\nbuild/server  # 对应于 examples/server.cpp\n```\n\n如果是 Ubuntu 20.04 的话需要手动升级一下 gcc 版本（默认的 g++-9 不支持协程）：\n\n```bash\nsudo apt install -y g++-10 libstdc++-10-dev\nexport CXX=g++-10\nrm -rf build\ncmake -B build -DCO_ASYNC_DEBUG=ON\ncmake --build build --parallel 8\nbuild/server  # 对应于 examples/server.cpp\n```\n\n\u003e 此处开启的 `-DCO_ASYNC_DEBUG=ON` 选项可以检测潜在的漏洞。\n\n如果你的 Linux 内核版本是 5.x，可能还需要开启这个选项：\n\n```bash\ncmake -B build -DCO_ASYNC_DEBUG=ON -DCO_ASYNC_INVALFIX=ON\n```\n\n\u003e Linux 6.x 内核则无需开启，你可以通过 `uname -r` 查询内核版本。\n\n### Docker 环境构建\n\n如果你的 Ubuntu 标准库版本太老，无法编译，可以试试看小彭老师提供的 [Docker 环境](Dockerfile)：\n\n```bash\ndocker build -t my_archlinux_image .             # 构建 Docker 镜像\ndocker run -it -p 8080:8080 my_archlinux_image   # 运行并进入 Docker 镜像，映射端口 8080 到本机\n```\n\n在 Docker 容器中，构建本项目：\n\n```bash\ncmake -B build\ncmake --build build --parallel 8\nbuild/server  # 对应于 examples/server.cpp\n```\n\n\u003e Docker 继承宿主机的 Linux 内核版本，因此 Docker 无法解决 Linux 内核版本过低的问题。\n\n\u003e 同样地，不建议使用 WSL，因为 WSL 的 Linux 内核版本是固定的，无法升级，而且非常老，常常是 4.x。\n\n### Windows\n\n- Windows \u003e= 10（施工中，稍后支持）\n- Visual Studio \u003e= 2022（施工中，稍后支持）\n\n## 安装与导入\n\n### 作为普通库导入\n\n将本项目下载到你的项目中作为子文件夹，引入并链接：\n\n```cmake\nadd_subdirectory(co_async)\ntarget_link_libraries(你的名字 PRIVATE co_async)\n```\n\n在你的代码中导入主头文件即可：\n\n```cpp\n#include \u003cco_async/co_async.hpp\u003e\n```\n\n### 作为单头文件导入\n\n下载 [scripts/single_co_async.hpp](scripts/single_co_async.hpp)，然后：\n\n```cpp\n#define CO_ASYNC_IMPLEMENTATION  // 在其中一个 cpp 文件中定义该宏\n#include \u003csingle_co_async.hpp\u003e\n```\n\nLinux 编译选项：`-std=c++20 -I 本项目根目录 -luring -lbearssl`\n\n- liburing \u003e= 2.6\n- bearssl \u003e= 0.6\n\n### 额外 CMake 选项\n\n```bash\ncmake -B build -DCO_ASYNC_DEBUG=ON  # 启用调试与安全性检测\ncmake -B build -DCO_ASYNC_EXCEPT=ON  # 启用异常（会影响协程函数性能）\ncmake -B build -DCO_ASYNC_PERF=ON  # 启用性能测试（程序结束时自动打印测时结果）\ncmake -B build -DCO_ASYNC_ZLIB=ON  # 启用压缩支持（需要链接 /usr/lib/libz.so）\ncmake -B build -DCO_ASYNC_STEAL=ON  # 启用多线程任务窃取（类似于 TBB）\ncmake -B build -DCO_ASYNC_ALLOC=ON  # 启用自定义分配器（基于 C++17 PMR）\ncmake -B build -DCO_ASYNC_DIRECT=ON  # 启用直接 IO 轮询（仅限数据库应用场景）\ncmake -B build -DCO_ASYNC_INVALFIX=ON  # 尝试修复低 Linux 内核版本的错误\ncmake -B build -DCO_ASYNC_NATIVE=ON  # 启用本机指令集（-march=native）\ncmake -B build -DCO_ASYNC_WARN=ON  # 启用警告（-Wall -Wextra -Werror）\ncmake -B build -DCO_ASYNC_JEMALLOC=ON  # 启用 Jemalloc 分配器\n```\n\n## 性能测试\n\n测试平台：\n\n- AMD Ryzen 7 7800X3D（8 核心 16 线程 4.5 GHz）\n- Linux 内核：6.8.2\n- GCC 编译器：13.2.1\n- 内存：2 x 16 GB（DDR5 4800 MHz）\n\n测试结果：\n\n- 普通函数调用 25ns\n- 协程函数调用 80ns\n- 协程函数调用（启用异常）150ns\n- I/O 基础延迟 0.8µs\n- 打开文件 7µs\n- 查询文件信息 11µs\n- 读写 ~1MB 文件 80µs\n\n百万并发 HTTP 压力测试 [examples/server_mt.cpp](examples/server_mt.cpp)：\n\n```\n$ wrk -t16 -c1000 -d20s http://127.0.0.1:8080/\nRunning 20s test @ http://127.0.0.1:8080/\n  16 threads and 1000 connections\n  Thread Stats   Avg      Stdev     Max   +/- Stdev\n    Latency     1.58ms    6.07ms 222.19ms   98.78%\n    Req/Sec    79.18k     9.15k  154.00k    94.73%\n  25281650 requests in 20.09s, 2.83GB read\nRequests/sec: 1258548.22\nTransfer/sec:    144.03MB\n```\n","funding_links":[],"categories":["网络"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farchibate%2Fco_async","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farchibate%2Fco_async","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farchibate%2Fco_async/lists"}