开源项目C++ Workflow学习

📅 2026/7/5 2:33:35 👁️ 阅读次数 📝 编程学习
开源项目C++ Workflow学习

Workflow是一个面向高并发网络服务的异步编程框架。它最核心的思想是:

把所有异步操作抽象成任务(Task),再把任务组织成工作流(Workflow)。

很多传统 C++ 网络库只负责网络 I/O,而 Workflow 希望把网络、文件、计算、定时器等全部统一到同一种任务模型中。


一、Workflow 的主要特点

1. 全异步、非阻塞

Workflow 中几乎所有 I/O 都是异步的:

  • HTTP
  • HTTPS
  • Redis
  • MySQL
  • DNS
  • 文件 I/O

例如:

WFHttpTask *task = WFTaskFactory::create_http_task( "http://www.baidu.com", 0, 0, callback); task->start();

调用start()后立即返回。

真正的数据收发在后台线程中完成。

当任务结束时:

callback(task);

才会被自动调用。

因此:

  • 不会阻塞线程
  • 不需要手动管理 epoll
  • 不需要自己写事件循环

2. 串行任务流(Series)

Workflow 最大特色之一。

多个异步任务可以写成:

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 底层采用:

  • epoll(Linux)
  • kqueue(BSD/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. 状态机驱动

每个网络任务实际上都是一个状态机。

例如 HTTP:

INIT ↓ DNS ↓ CONNECT ↓ SEND ↓ RECV ↓ PARSE ↓ DONE

源码中大量存在:

switch(state) { case ST_CONNECT: ... case ST_RECV: ... }

网络事件不断推动状态机向前运行。


3. SeriesWork

源码中:

SeriesWork

内部维护:

std::queue<SubTask *>

执行流程:

当前任务完成 ↓ done() ↓ SeriesWork::pop() ↓ 启动下一个任务

所以:

series_of(task)->push_back(next);

只是把任务加入队列。


4. ParallelWork

内部维护:

剩余任务计数器

每个 Series 完成:

counter--

当:

counter == 0

触发最终回调。

类似:

CountDownLatch

5. Executor 线程池

网络线程不能执行:

数据库解析 JSON解析 压缩 业务逻辑

否则会阻塞整个 Reactor。

因此:

IO线程 ↓ 任务完成 ↓ 投递到Executor线程池 ↓ 执行回调

实现:

生产者消费者模型

大致:

while (true) { task = queue.pop(); task->dispatch(); }

6. 连接池

对于:

HTTP KeepAlive MySQL Redis

Workflow 内置连接池。

连接不会每次:

connect() close()

而是:

获取空闲连接 ↓ 使用 ↓ 归还池中

极大减少系统调用开销。


四、为什么 Workflow 性能高?

原因主要有:

  1. 全异步非阻塞
  2. epoll 事件驱动
  3. Reactor 与业务线程分离
  4. 连接复用
  5. 减少线程切换
  6. 大量无锁/低锁设计
  7. 统一任务调度模型
  8. 状态机驱动而不是阻塞等待