Workflow是一个面向高并发网络服务的异步编程框架。它最核心的思想是把所有异步操作抽象成任务Task再把任务组织成工作流Workflow。很多传统 C 网络库只负责网络 I/O而 Workflow 希望把网络、文件、计算、定时器等全部统一到同一种任务模型中。一、Workflow 的主要特点1. 全异步、非阻塞Workflow 中几乎所有 I/O 都是异步的HTTPHTTPSRedisMySQLDNS文件 I/O例如WFHttpTask *task WFTaskFactory::create_http_task( http://www.baidu.com, 0, 0, callback); task-start();调用start()后立即返回。真正的数据收发在后台线程中完成。当任务结束时callback(task);才会被自动调用。因此不会阻塞线程不需要手动管理 epoll不需要自己写事件循环2. 串行任务流SeriesWorkflow 最大特色之一。多个异步任务可以写成HTTP请求 ↓ 解析数据 ↓ MySQL查询 ↓ Redis缓存 ↓ 返回客户端代码WFHttpTask *t1 ... WFMySQLTask *t2 ... series_of(t1)-push_back(t2);框架保证t1完成 ↓ 执行回调 ↓ 自动执行t2开发者不需要自己维护状态机。传统异步编程回调嵌套地狱Workflow任务链3. 并行任务ParallelWork多个任务可同时执行ParallelWork *pw Workflow::create_parallel_work(cb); pw-add_series(s1); pw-add_series(s2); pw-add_series(s3); pw-start();框架自动等待所有任务完成 ↓ 执行最终回调非常适合多数据库查询聚合服务微服务调用例如用户信息 订单信息 推荐信息同时请求。4. 高性能Workflow 底层采用epollLinuxkqueueBSD/macOS实现单机百万连接。特点Reactor 线程池并且无锁设计较多连接池内存池零拷贝都做了优化。5. 内置协议丰富支持协议支持HTTP/HTTPS√Redis√MySQL√Kafka√DNS√文件IO√开发者不需要再找第三方客户端。6. 统一任务模型所有任务都继承自SubTask包括网络任务 文件任务 定时器任务 计算任务统一接口task-start();二、Workflow 的总体架构框架大致如下用户代码 │ WFTaskFactory │ 创建各种Task │ ------------- | SubTask | ------------- │ ------------------------ │ │ SeriesWork ParallelWork │ │ ------------------------ │ Scheduler │ ------------------ │ │ Reactor线程 Executor线程 │ │ epoll 计算/回调三、核心实现机制1. Reactor 模型Workflow 使用经典Reactor epoll架构。每个 Reactor 线程while (true) { epoll_wait(); 处理可读事件; 处理可写事件; 超时处理; }流程socket可读 ↓ epoll通知 ↓ Reactor线程处理 ↓ 数据读入缓冲区 ↓ 任务状态推进Reactor 线程只做网络IO 状态切换不会执行耗时业务逻辑。2. 状态机驱动每个网络任务实际上都是一个状态机。例如 HTTPINIT ↓ DNS ↓ CONNECT ↓ SEND ↓ RECV ↓ PARSE ↓ DONE源码中大量存在switch(state) { case ST_CONNECT: ... case ST_RECV: ... }网络事件不断推动状态机向前运行。3. SeriesWork源码中SeriesWork内部维护std::queueSubTask *执行流程当前任务完成 ↓ done() ↓ SeriesWork::pop() ↓ 启动下一个任务所以series_of(task)-push_back(next);只是把任务加入队列。4. ParallelWork内部维护剩余任务计数器每个 Series 完成counter--当counter 0触发最终回调。类似CountDownLatch5. Executor 线程池网络线程不能执行数据库解析 JSON解析 压缩 业务逻辑否则会阻塞整个 Reactor。因此IO线程 ↓ 任务完成 ↓ 投递到Executor线程池 ↓ 执行回调实现生产者消费者模型大致while (true) { task queue.pop(); task-dispatch(); }6. 连接池对于HTTP KeepAlive MySQL RedisWorkflow 内置连接池。连接不会每次connect() close()而是获取空闲连接 ↓ 使用 ↓ 归还池中极大减少系统调用开销。四、为什么 Workflow 性能高原因主要有全异步非阻塞epoll 事件驱动Reactor 与业务线程分离连接复用减少线程切换大量无锁/低锁设计统一任务调度模型状态机驱动而不是阻塞等待
开源项目C++ Workflow学习
发布时间:2026/7/5 2:30:26
Workflow是一个面向高并发网络服务的异步编程框架。它最核心的思想是把所有异步操作抽象成任务Task再把任务组织成工作流Workflow。很多传统 C 网络库只负责网络 I/O而 Workflow 希望把网络、文件、计算、定时器等全部统一到同一种任务模型中。一、Workflow 的主要特点1. 全异步、非阻塞Workflow 中几乎所有 I/O 都是异步的HTTPHTTPSRedisMySQLDNS文件 I/O例如WFHttpTask *task WFTaskFactory::create_http_task( http://www.baidu.com, 0, 0, callback); task-start();调用start()后立即返回。真正的数据收发在后台线程中完成。当任务结束时callback(task);才会被自动调用。因此不会阻塞线程不需要手动管理 epoll不需要自己写事件循环2. 串行任务流SeriesWorkflow 最大特色之一。多个异步任务可以写成HTTP请求 ↓ 解析数据 ↓ MySQL查询 ↓ Redis缓存 ↓ 返回客户端代码WFHttpTask *t1 ... WFMySQLTask *t2 ... series_of(t1)-push_back(t2);框架保证t1完成 ↓ 执行回调 ↓ 自动执行t2开发者不需要自己维护状态机。传统异步编程回调嵌套地狱Workflow任务链3. 并行任务ParallelWork多个任务可同时执行ParallelWork *pw Workflow::create_parallel_work(cb); pw-add_series(s1); pw-add_series(s2); pw-add_series(s3); pw-start();框架自动等待所有任务完成 ↓ 执行最终回调非常适合多数据库查询聚合服务微服务调用例如用户信息 订单信息 推荐信息同时请求。4. 高性能Workflow 底层采用epollLinuxkqueueBSD/macOS实现单机百万连接。特点Reactor 线程池并且无锁设计较多连接池内存池零拷贝都做了优化。5. 内置协议丰富支持协议支持HTTP/HTTPS√Redis√MySQL√Kafka√DNS√文件IO√开发者不需要再找第三方客户端。6. 统一任务模型所有任务都继承自SubTask包括网络任务 文件任务 定时器任务 计算任务统一接口task-start();二、Workflow 的总体架构框架大致如下用户代码 │ WFTaskFactory │ 创建各种Task │ ------------- | SubTask | ------------- │ ------------------------ │ │ SeriesWork ParallelWork │ │ ------------------------ │ Scheduler │ ------------------ │ │ Reactor线程 Executor线程 │ │ epoll 计算/回调三、核心实现机制1. Reactor 模型Workflow 使用经典Reactor epoll架构。每个 Reactor 线程while (true) { epoll_wait(); 处理可读事件; 处理可写事件; 超时处理; }流程socket可读 ↓ epoll通知 ↓ Reactor线程处理 ↓ 数据读入缓冲区 ↓ 任务状态推进Reactor 线程只做网络IO 状态切换不会执行耗时业务逻辑。2. 状态机驱动每个网络任务实际上都是一个状态机。例如 HTTPINIT ↓ DNS ↓ CONNECT ↓ SEND ↓ RECV ↓ PARSE ↓ DONE源码中大量存在switch(state) { case ST_CONNECT: ... case ST_RECV: ... }网络事件不断推动状态机向前运行。3. SeriesWork源码中SeriesWork内部维护std::queueSubTask *执行流程当前任务完成 ↓ done() ↓ SeriesWork::pop() ↓ 启动下一个任务所以series_of(task)-push_back(next);只是把任务加入队列。4. ParallelWork内部维护剩余任务计数器每个 Series 完成counter--当counter 0触发最终回调。类似CountDownLatch5. Executor 线程池网络线程不能执行数据库解析 JSON解析 压缩 业务逻辑否则会阻塞整个 Reactor。因此IO线程 ↓ 任务完成 ↓ 投递到Executor线程池 ↓ 执行回调实现生产者消费者模型大致while (true) { task queue.pop(); task-dispatch(); }6. 连接池对于HTTP KeepAlive MySQL RedisWorkflow 内置连接池。连接不会每次connect() close()而是获取空闲连接 ↓ 使用 ↓ 归还池中极大减少系统调用开销。四、为什么 Workflow 性能高原因主要有全异步非阻塞epoll 事件驱动Reactor 与业务线程分离连接复用减少线程切换大量无锁/低锁设计统一任务调度模型状态机驱动而不是阻塞等待