当前位置: 首页 > ds >正文

epoll+线程池

1、初始化线程池

 2、获取时间

 3、首次响应客户端连接

 4、创建epoll实例

 5、创建任务队列

 6、处理新连接的任务

 7、消费者函数

 8、从队列里取任务

 9、确认线程是否存活

 10、生产者添加任务

 11、向任务队列中添加任务

 12、管理者线程函数

 

 13、处理客户端请求任务函数

 14、epoll_listen监听套接字

 15、创建线程池

 16、主函数

 

编译

gcc *.c -I../include -L. -lthread_pool -lpthread -o app

测试

nc 169.254.196.205 8080

总结

以下是**所有函数的分类总结**,按 **“模块职责+核心逻辑”** 梳理,帮你快速关联记忆:  

 

 

### **一、网络初始化模块(TCP 服务器启动)**  

| 函数名 | 功能 & 核心逻辑 | 作用 |

|-----------------|-----------------------------------------------------------------------------|----------------------------------------------------------------------|

| `INET_INIT` | 创建 TCP 套接字 → 填充 `sockaddr_in`(绑定任意 IP、端口转网络序) → `bind` → `listen` | 启动 TCP 监听,返回监听套接字,是服务器的**入口基础** |  

 

 

### **二、时间处理模块(辅助工具)**  

| 函数名 | 功能 & 核心逻辑 | 作用 |

|--------------|--------------------------------------------------------------------------|----------------------------------------------------------------------|

| `GET_TIME` | 用 `time_t` 获取当前时间 → `ctime_r`(线程安全)转字符串 → 移除换行符(`\n` 改 `\0`) | 为日志、响应生成**格式化时间字符串**,避免线程安全问题 |  

 

 

### **三、客户端交互模块(连接响应、请求处理)**  

| 函数名 | 功能 & 核心逻辑 | 作用 |

|-------------------|-----------------------------------------------------------------------------|----------------------------------------------------------------------|

| `FIRST_RESPONSE` | 调用 `GET_TIME` 获取时间 → 拼接客户端 IP/端口 → `send` 欢迎消息(带 `MSG_NOSIGNAL` 避免 `SIGPIPE`) | 客户端**首次连接时的响应**,告知连接成功 |

| `response_task` | 循环非阻塞 `recv`(`MSG_DONTWAIT`) → 解析命令(如 `time` 则返回当前时间) → 连接关闭时清理 `epoll` | 处理客户端**持续数据交互**,支持命令响应、连接释放 |  

 

 

### **四、epoll 多路复用模块(高效 IO 监听)**  

| 函数名 | 功能 & 核心逻辑 | 作用 |

|---------------|----------------------------------------------------------------------------|----------------------------------------------------------------------|

| `epoll_init` | `epoll_create` 创建实例 → 构造 `epoll_event`(边缘触发 `EPOLLET` + 读事件 `EPOLLIN`) → `epoll_ctl_add` 监听套接字 | 初始化 epoll,让服务器**高效监听新连接/数据事件** |

| `epoll_listen`| `epoll_wait` 阻塞等事件 → 区分“新连接”(提交 `accept_task`)和“客户端数据”(提交 `response_task`) → 循环处理 | 服务器**事件分发核心**,将 IO 事件转为线程池任务 |  

 

 

### **五、任务队列模块(生产者-消费者解耦)**  

| 函数名 | 功能 & 核心逻辑 | 作用 |

|---------------|-----------------------------------------------------------------------------|----------------------------------------------------------------------|

| `queue_create`| 分配队列内存(控制结构 + 任务数组) → 初始化 `front`/`rear`/`cur`/`max`(环形队列) | 创建**线程安全的任务缓冲区**,解耦生产者(如 epoll)和消费者(工作线程) |

| `queue_en` | 检查队列满 → 任务加入队尾(`rear` 循环后移:`rear=(rear+1)%max`) → `cur++` | 生产者**安全入队**,用环形队列避免“假溢出” |

| `queue_de` | 检查队列空 → 取出队首任务(`front` 循环后移:`front=(front+1)%max`) → `cur--` | 消费者**安全出队**,保证任务有序执行 |  

 

 

### **六、线程池模块(并行任务处理)**  

#### **1. 线程池创建 & 基础**  

| 函数名 | 功能 & 核心逻辑 | 作用 |

|-----------------------|-----------------------------------------------------------------------------|----------------------------------------------------------------------|

| `threads_pool_create` | 分配线程池内存 → 初始化状态(核心线程、最大线程、任务队列等) → 创建**核心工作线程**(`customer`)和**管理器线程**(`manager`) | 构建线程池基础,是**并行处理的核心载体** |  

 

 

#### **2. 任务生产(生产者逻辑)**  

| 函数名 | 功能 & 核心逻辑 | 作用 |

|---------------------|-----------------------------------------------------------------------------|----------------------------------------------------------------------|

| `producer_add_task` | 检查线程池运行状态 → 加锁保护队列 → 队列满则等 `not_full` → 入队后通知 `not_empty` → 解锁 | 生产者(如 `epoll_listen`)**安全提交任务**到线程池 |

| `accept_task` | `accept` 新连接 → 解析客户端 IP/端口(`inet_ntop`/`ntohs`) → 新套接字加入 epoll → 调用 `FIRST_RESPONSE` | 处理**新客户端连接的任务逻辑**,是线程池的典型“生产任务” |  

 

 

#### **3. 任务消费(工作线程逻辑)**  

| 函数名 | 功能 & 核心逻辑 | 作用 |

|------------|-----------------------------------------------------------------------------|----------------------------------------------------------------------|

| `customer` | 加锁 → 队列空则等 `not_empty` → 检查退出条件 → 出队执行任务(`tmp.work(tmp.arg)`) → 解锁更新状态 | 线程池的**消费者**,循环从队列取任务并行执行 |  

 

 

#### **4. 线程池管理(动态调整)**  

| 函数名 | 功能 & 核心逻辑 | 作用 |

|-----------|-----------------------------------------------------------------------------|----------------------------------------------------------------------|

| `manager` | 监控线程池状态(活跃线程、忙碌线程、任务队列) → 任务满/忙碌比例高则**扩容**,空闲多则**缩容** → 写日志 | 动态优化线程池资源,避免线程过多/过少影响性能 |  

 

 

### **七、辅助工具函数**  

| 函数名 | 功能 & 核心逻辑 | 作用 |

|----------------|----------------------------------------------------------------------|----------------------------------------------------------------------|

| `thread_alive` | 用 `pthread_kill(tid, 0)` 检查线程状态 → `ESRCH` 错误表示线程已终止 | 判断线程是否存活,为 `manager` 动态调整提供依据 |  

 

 

### **记忆口诀(串联核心流程)**  

1. **启动**:`INET_INIT` 建监听 → `epoll_init` 开多路 → `threads_pool_create` 起线程池  

2. **事件循环**:`epoll_listen` 等事件 → 新连接/数据转任务 → `producer_add_task` 入队列  

3. **任务处理**:`customer` 线程取任务 → 执行 `accept_task`/`response_task` → 交互/响应客户端  

4. **动态优化**:`manager` 监控状态 → 自动扩容/缩容 → 平衡性能与资源  

 

 

通过 **“模块分类 + 核心逻辑 + 流程串联”**,可快速记住每个函数的职责和协作关系,重点关注 **epoll 事件分发、线程池生产消费、动态调整** 这三条主线!

http://www.xdnf.cn/news/12935.html

相关文章:

  • 正点原子[第三期]Arm(iMX6U)Linux移植学习笔记-12.1 Linux内核启动流程简介
  • 第二章 无刷电机硬件控制
  • 31.2linux中Regmap的API驱动icm20608实验(编程)_csdn
  • Prompt Enginering(提示工程)先进技术
  • 基于FPGA的超声波显示水位距离,通过蓝牙传输水位数据到手机,同时支持RAM存储水位数据,读取数据。
  • 关于 ffmpeg设置摄像头报错“Could not set video options” 的解决方法
  • Kubernetes 节点资源驱逐策略详解:evictionHard 与 evictionSoft
  • 附加模块--Qt OpenGL模块功能及架构
  • 利用pandas gradio实现简单的项目子项拆解及排期
  • Fractal Generative Models论文阅读笔记与代码分析
  • 树莓派超全系列教程文档--(57)如何设置 Apache web 服务器
  • 抖音怎么下载没有水印的视频?
  • ArkUI-X与Android桥接通信之方法回调
  • 华为OD机试真题——机房布局(2025B卷:100分)Java/python/JavaScript/C++最佳实现
  • LeetCode - 53. 最大子数组和
  • 【每日一题 | 2025年6.2 ~ 6.8】第16届蓝桥杯部分偏简单题
  • 大数据治理的常见方式
  • Unity VR/MR开发-VR/开发SDK选型对比分析
  • 20-Oracle 23 ai free Database Sharding-特性验证
  • 求解插值多项式及其余项表达式
  • 阿里云OSS 上传文件 Python版本
  • Xxl-job——源码设计思考
  • 2025年6月6日第一轮
  • 基于算法竞赛的c++编程(20)函数的递归
  • Spring Security深度解析:构建企业级安全框架
  • 港科大快手提出统一上下文视频编辑 UNIC,各种视频编辑任务一网打尽,还可进行多项任务组合!
  • MQTT协议详解技术文档
  • 微服务架构实战:Nacos 单机版的安装与启动流程
  • 号外!PLC和安川伺服,通过Profinet转EtherCAT网关同步多个工作站的运动
  • 坚持每日Codeforces三题挑战:Day 4 - 题目详解(2025-06-07,难度:1000, 1100, 1400)