Skip to content

Commit 208e4d0

Browse files
committed
Add one article about how to use acl fiber pool.
1 parent be19aa8 commit 208e4d0

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed

fiber_pool.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
---
2+
title: Acl 协程池使用指南
3+
date: 2025-03-31 21:00:00
4+
tags: 协程编程
5+
categories: 协程编程
6+
---
7+
8+
# Acl 协程池使用指南
9+
10+
## 一、说明
11+
12+
相对于线程而言,协程更加轻量,占用更少的资源,但协程也是有成本的,如果频繁地创建与释放协程,也会占用大量的CPU,而使用协程池便可以有效地解决这一问题;Acl协程模块提供了协程池功能,采用C++11语法,简单易用,下面是Acl协程池的功能要点:
13+
- **动态性:** 这就意味着池子的大小在最小值与最大值之间浮动,按需创建与使用;
14+
- **半驻留:** 协程池中的协程空闲一段时间后,如果没有新的待执行任务且池子中协程数量大于最小值时,会自动退出;
15+
- **同步异步:** 通过调整任务缓冲大小,实现任务以同步或异步执行,同步模式使任务执行更具实时性,而异步模式则可以提升并行执行效率;
16+
- **共享栈:** 可以使协程池中的协程以“共享栈”模式运行,当池子中数量非常多时,可以有效地减少内存占用。
17+
18+
## 二、使用举例
19+
20+
### 2.1 一个简单的示例
21+
22+
```c++
23+
void mytest(int i) {
24+
printf("Task %d is running\n", i);
25+
}
26+
27+
void test() {
28+
// 创建一个协程对象,各个参数如下:
29+
// 最小协程数:1
30+
// 最大协程数:20
31+
// 协程空闲退出时间:60秒
32+
// 协程池中任务队列的缓冲区大小:500
33+
// 每个协程栈大小:64000字节
34+
// 协程池中的协程是否采用共享栈模式:否
35+
acl::fiber_pool pool(1, 20, 60, 500, 64000, false);
36+
int i = 0;
37+
38+
// 在协程池中执行第一个任务,捕获外部变量.
39+
pool.exec([i]() {
40+
printf("Task %d is running\n", i);
41+
});
42+
i++;
43+
44+
// 在协程池中执行第二个任务,通过变参方式传递参数.
45+
pool.exec([](int i) {
46+
printf("Task %d is running\n", i);
47+
}, i);
48+
i++;
49+
50+
// 在协程池中执行第三个任务,将变参传递给普通函数.
51+
pool.exec(mytest, i);
52+
53+
// 开始协程调度过程.
54+
acl::fiber::schedule();
55+
}
56+
```
57+
58+
上面例子展示了从协程池的创建到任务添加与执行的过程,期中任务添加方法`exec`在添加任务时,允许用户使用lambda表达式或普通函数做为执行过程,并允许捕获外部变量及传递变参。下面给出协程池创建时各个参数的含义:
59+
60+
- **最大最小协程数:** 这两个参数分别限制了协程池中所创建协程的最大最小数量,当要执行的任务比较多且繁重时,所创建的协程可能就比较多,否则创建的协程就比较少;
61+
- **空闲协程生命周期:** 当任务比较少时,如果总协程数大于`最小协程数`,则有些空闲的协程就会自动退出,以减少资源使用;
62+
- **任务池缓冲:** 在创建协程池时,任务缓冲大小表明了任务添加的异步性,即执行`exec`时任务的添加与执行是异步的,不需要等待一个协程收到任务后该方法才返回;如果想要同步添加任务,则可以将任务缓冲buf设为0;
63+
- **协程栈大小及共享栈:** 协程池中每个所建协程的栈空间大小是可以单独设定的,另外,还可以指定这些协程是否采用`共享协程栈`方式;当协程数量比较多时,采用`共享协程栈`方式可以节省较多内存。
64+
65+
### 2.2 等待任务完成示例
66+
67+
如果想要执行一批任务,并且等待所有任务完成,该如何实现?下面稍微修改前面例子,增加同步机制来等待一批任务的完成。
68+
69+
```c++
70+
void mytest(acl::wait_group& wg, int i) {
71+
printf("Task %d is running\n", i);
72+
wg.done(); // 通知完成当前任务
73+
}
74+
75+
void test() {
76+
acl::fiber_pool pool(1, 20, 60, 500, 64000, false);
77+
acl::wait_group wg;
78+
int i = 0;
79+
80+
wg.add(1);
81+
pool.exec([&wg, i]() {
82+
printf("Task %d is running\n", i);
83+
wg.done(); // 通知完成当前任务
84+
});
85+
i++;
86+
87+
wg.add(1);
88+
pool.exec([&wg](int i) {
89+
printf("Task %d is running\n", i);
90+
wg.done(); // 通知完成当前任务
91+
}, i);
92+
i++;
93+
94+
wg.add(1);
95+
pool.exec(mytest, std::ref(wg), i);
96+
97+
go[&wg, &pool] { // 创建独立的协程等待所有任务完成
98+
wg.wait(); // 等待所有任务完成
99+
printf("All tasks finished!\r\n");
100+
pool.stop(); // 停止协程池
101+
};
102+
}
103+
```
104+
105+
该例子通过引入 acl::wait_group 对象,实现了任务完成后的同步过程。
106+
107+
## 三、参考链接
108+
- **一个协程池例子:** https://github.com/acl-dev/demo/blob/master/c%2B%2B1x/fiber/fiber_pool.cpp
109+
- **非阻塞IO+协程池回显例子:** https://github.com/acl-dev/demo/blob/master/c%2B%2B1x/fiber/fiber_nio_echod.cpp
110+
- **非阻塞IO+协程池HTTP服务:** https://github.com/acl-dev/demo/blob/master/c%2B%2B1x/fiber/fiber_nio_httpd.cpp
111+
- **下载Acl工程:** https://github.com/acl-dev/acl/
112+
- **Acl 网络协程框架编程指南:** https://acl-dev.cn/2019/04/07/fiber/

0 commit comments

Comments
 (0)