https://github.com/youngyangyang04/muduo-core
【代码随想录知识星球】项目分享-muduo核心实现
https://github.com/youngyangyang04/muduo-core
Last synced: 7 months ago
JSON representation
【代码随想录知识星球】项目分享-muduo核心实现
- Host: GitHub
- URL: https://github.com/youngyangyang04/muduo-core
- Owner: youngyangyang04
- Created: 2025-01-02T07:26:14.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-03-17T12:55:25.000Z (10 months ago)
- Last Synced: 2025-06-04T03:57:37.996Z (7 months ago)
- Language: C++
- Size: 91.8 KB
- Stars: 92
- Watchers: 2
- Forks: 28
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# muduo-core
【代码随想录知识星球】项目分享-muduo核心实现
## 项目介绍
本项目是参考 muduo 实现的基于 多Reactor 模型的多线程网络库。使用 C++ 11 编写去除 muduo 对 boost 的依赖。
项目已经实现了 Channel 模块、Poller 模块、事件循环模块、日志模块、线程池模块、一致性哈希轮询算法。
## 开发环境
* linux kernel version5.15.0-113-generic (ubuntu 22.04.6)
* gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
* cmake version 3.22
## 并发模型

项目采用主从 多Reactor多线程 模型,MainReactor 只负责监听派发新连接,在 MainReactor 中通过 Acceptor 接收新连接并通过设计好的轮询算法派发给 SubReactor,SubReactor 负责此连接的读写事件。
调用 TcpServer 的 start 函数后,会内部创建线程池。每个线程独立的运行一个事件循环,即 SubReactor。MainReactor 从线程池中轮询获取 SubReactor 并派发给它新连接,处理读写事件的 SubReactor 个数一般和 CPU 核心数相等。使用主从 Reactor 模型有诸多优点:
1. 响应快,不必为单个同步事件所阻塞,虽然 Reactor 本身依然是同步的;
2. 可以最大程度避免复杂的多线程及同步问题,并且避免多线程/进程的切换;
3. 扩展性好,可以方便通过增加 Reactor 实例个数充分利用 CPU 资源;
4. 复用性好,Reactor 模型本身与具体事件处理逻辑无关,具有很高的复用性;
## 构建项目
安装基本工具
```shell
sudo apt-get update
sudo apt-get install -y wget cmake build-essential unzip git
```
## 编译指令
下载项目
```shell
git clone https://github.com/youngyangyang04/muduo-core.git
```
进入到muduo-core文件
```shell
cd muduo-core
```
创建build文件夹,并且进入build文件:
```shell
mkdir build && cd build
```
然后生成可执行程序文件:
```shell
cmake .. && make -j${nproc}
```
运行程序,进入example文件夹,并且执行可执行程序
```shell
cd example && ./testserver
```
## 功能介绍
- **事件轮询与分发模块**:`EventLoop.*`、`Channel.*`、`Poller.*`、`EPollPoller.*`负责事件轮询检测,并实现事件分发处理。`EventLoop`对`Poller`进行轮询,`Poller`底层由`EPollPoller`实现。
- **线程与事件绑定模块**:`Thread.*`、`EventLoopThread.*`、`EventLoopThreadPool.*`绑定线程与事件循环,完成`one loop per thread`模型。
- **网络连接模块**:`TcpServer.*`、`TcpConnection.*`、`Acceptor.*`、`Socket.*`实现`mainloop`对网络连接的响应,并分发到各`subloop`。
- **缓冲区模块**:`Buffer.*`提供自动扩容缓冲区,保证数据有序到达。
## 技术亮点
1. **高并发非阻塞网络库**
`muduo`采用`Reactor`多模型多线程的结合,实现了高并发非阻塞的网络库。
2. **智能指针防止悬空指针**
`TcpConnection`继承自`enable_shared_from_this`,其目的是防止在不该被释放对象的地方释放对象,导致悬空指针的产生。
这样可以避免用户可能在处理`OnMessage`事件时删除对象,确保`TcpConnection`以正确方式释放。
3. **唤醒机制**
`EventLoop`中使用了`eventfd`来调用`wakeup()`,让`mainloop`唤醒`subloop`的`epoll_wait`阻塞。
4. **一致性哈希轮询算法**
新增`ConsistenHash`头文件,采用一致性哈希轮询算法,将`EventLoop`合理分发给每一个`TcpConnection`对象。
此外,支持自定义哈希函数,满足高并发需求。但需要注意虚拟节点数量不能过少。
5. **线程创建有序性**
在`Thread`中通过`C++ lambda`表达式以及信号量机制,保证线程创建的有序性,确保线程正常创建后再执行线程函数。
6. **非阻塞核心缓冲区**
`Buffer.*`是`muduo`网络库非阻塞的核心模块。当触发相应的读写事件时,内核缓冲区可能没有足够空间一次性发送数据,此时有两种选择:
- 第一种是将其设置为非阻塞,但可能造成 CPU 忙等待;
- 第二种是阻塞等待内核缓冲区有空间再发送,但效率低下。
为了解决这些问题,`Buffer`模块将多余数据存储在用户缓冲区,并注册相应的读写事件监听,待事件再次触发时统一发送。
7. **灵活的日志模块**
`Logger`支持设置日志等级。在调试代码时,可以开启`DEBUG`模式打印日志;而在服务器运行时,为了减少日志对性能的影响,可关闭`DEBUG`相关日志输出。
## 优化方向
- 完善内存池和完善异步日志缓冲区、定时器、连接池。
- 增加更多的测试用例,如HTTP、RPC。
- 可以考虑引入协程库等模块
## 致谢
- [作者-Shangyizhou]https://github.com/Shangyizhou/A-Tiny-Network-Library/tree/main
- [作者-S1mpleBug]https://github.com/S1mpleBug/muduo_cpp11?tab=readme-ov-file
- [作者-chenshuo]https://github.com/chenshuo/muduo
- 《Linux高性能服务器编程》
- 《Linux多线程服务端编程:使用muduo C++网络库》