IO模型与并发服务器
阻塞IO用户层charbuf[1024];recv(fd,buf,sizeof(0),0);//程序卡在这里等待数据内核1.检查socket接收缓冲区是否有数据2.若无数据将进程状态设为TASK_INTERRUPTIBLE(可中断睡眠)进程从CPU运行队列移出触发调度器切换其他进程运行3.数据到达网卡触发硬件中断→内核将数据拷贝到接收缓冲区唤醒进程(状态改为TASK_RUNNING)重新加入运行队列非阻塞IO用户层函数原型int fcntl(int fd, int cmd, .../* arg */);fcntl(fd,F_SETFL,O_NONBLOCK);//设置非阻塞标志while(1){intnrecv(fd,buf,sizeof(buf),0);if(n0)break;//数据就绪if(errno!EAGAIN)exit(1);//错误处理usleep(1000);//避免CPU占满}内核1.检查接收缓冲区无论是否就绪都立即返回结果2.无数据时返回EAGAIN错误码进程继续执行(不进入睡眠)IO多路复用IO多路复用是一种单线程或单进程管理多个描述符(如套接字)的技术核心是通过系统调用监视多个IO操作的状态当某个IO操作就绪(可读、可写或发生异常)时通知应用程序进行处理为什么需要多路复用1.提高并发性能2.非阻塞IO协作3.高效管理大量连接select函数头文件#includesys/socket.h#includesys/types.h函数原型intselect(intnfds,fd_set*readfds,fd_set*writefds,fd_set*exceptfds,structtimeval*timeout);参数nfds要监视的最大的文件描述符1readfds要监视的读文件描述符集合如果不关心可以传NULLwritefds要监视的写文件描述符集合如果不关心可以传NULLexceptfds要监视的异常文件描述符集合如果不关心可以传NULLtimeout超过时间如果是NULL表示永久阻塞 返回值成功返回就绪的文件描述符的个数失败返回-1(并重置错误码)poll函数头文件#includesys/socket.h#includesys/types.h函数原型intpoll(structpollfd*fds,nfds_tnfds,inttimeout);参数fds一个指向pollfd结构体数组的指针它描述了要监视的文件描述符及其事件 nfdsfds数组中有效描述符元素的数量 timeout是等待时间单位为毫秒 返回值成功返回结构体中revents域不为0的的文件描述符的个数 如果在超时前没有任何事件发生poll()返回0失败返回-1(并重置错误码)服务器模型服务器模型有两种循环服务器、并发服务器循环服务器循环服务器在同一时刻只能响应一个客户端的请求并发服务器并发服务器在同一时刻可以响应多个客户端的请求TCP服务器默认的就是一个循环服务器因为有两个阻塞的函数accept和reve之间互相影响UDP服务器默认的就是一个并发服务器因为只有一个阻塞的函数recvfrom多线程并发服务器实现原理主线程负责接听新连接(accept)子线程每个线程处理一个连接的读写recv()/send()流程多进程并发服务器实现原理fork()模型1.主进程监听连接子进程处理请求2.父子进程完全独立崩溃互不影响预fork()优化1.启动时预先创建多个子进程(类似Apache)2.通过共享监听Socket(SO_REUSEPORT)实现负载均衡主进程1.创建监听Socket→bind()→listen()2.while(1){accept()接收新连接→fork()创建子进程处理连接}子进程1.close()关闭监听Socket(继承自父进程)2.recv()/send()处理客户端请求3.exit()退出IO多路复用并发服务器主线程1.创建监听Socket→bind()→listen()2.初始化fd_set集合将监听Socket加入集合3.while(1){select()监听所有fd→返回就绪的fd数量for(每个就绪的fd){if(是监听Socket)→accept()新连接并加入fd_setelse→recv()/send()处理数据}}pollfd结构体struct pollfd{int fd; //文件描述符short events; //等待的事件short revents; //实际发生的事件};事件常值说明**读事件**POLLIN普通或优先带数据可读POLLPRI高优先级数据可读**写事件**POLLOUT普通或优先带数据可写POLLWRNORM高优先级数据可写**错误事件**POLLERR发生错误POLLHUP发生挂起POLLNVAL描述不是打开的文件简述五种IO模型并说明是同步操作还是异步操作阻塞式I/O是最流行的I/O模型默认的情况下所有套接字都是阻塞的非阻塞式I/O设置成非阻塞是通知进程当所请求的I/O操作非得把本进程置于休眠状态才能完成时则不要置于休眠状态而是返回一个错误I/O多路复用同时阻塞监听多个I/O操作任意一个或多个触发后都会继续执行信号驱动式I/O内核在描述符就绪时会发送SIGIO信号通知异步I/O给内核传递描述符缓冲区指针、缓冲区大小和文件偏移并告知内核在操作完成后如何通知我们同步I/O操作指导致阻塞进程直到I/O操作完成的操作异步I/O操作不会导致请求阻塞。上述五种除了异步I/O外的其他四种都是同步I/O简述三种IO多路复用方法以及各自的特点select(最古老) 时间复杂度O(n) 触发水平触发模式 LT机制通过一个固定大小的位掩码(位图)来监控文件描述符集合每次调用需将集合从用户态全量拷贝到内核态内核暴力遍历所有fd检查状态。特点select支持的文件描述符最多是1024随fd增多性能线性下降每次遍历后需要重置集合。poll(对select的改进) 时间复杂度O(n) 触发水平触发模式 LT机制采用动态数组struct pollfd同样需全量拷贝和内核遍历特点无最大连接数限制但高并发下性能仍随fd数量线性下降用户态和内核态拷贝开销依然存在epoll(Linux高性能方案) 时间复杂度O(1) 触发水平/边沿触发模式 LT/ET机制内核维护红黑树管理fd通过回调机制(事件就绪时主动加入就绪链表 )调用epoll_wait仅返回就绪fd且采用内存映射(mmap)减少拷贝。特点水平触发(LT默认)和边沿触发(ET)两种模式海量连接下性能稳定(仅活跃连接数相关)是Nginx,Redis等高性能服务器的首选水平触发(LT,Level-Triggered)定义当文件描述符(fd)处于就绪状态(比如接收缓冲区有数据可读)时内核就会一直返回该fd直到你不再满足就绪条件(比如把数据读完)特点通知特点只要缓冲区还有数据epoll_wait每次都会返回该FD重复提醒找到你处理完。编程难度简单。允许每次只读一部分不用担心漏数据适合传统阻塞编程。性能开销频繁就绪时可能多次唤醒进程但内核遍历成本可控。适用场景通用型大多数业务服务器首选(如Redis)默认模式稳妥可靠。边沿触发(ET,Edge-Triggered)定义仅当fd的状态发生变化(从不可读变为可读或从不可写变为可写)的那一瞬间内核才返回该fd。此后即使缓冲区仍有数据只要状态不再变化内核也不再通知。特点通知特点仅当fd状态发生变化的瞬间(如无数据→有数据)通知一次之后即使有残留数据也不再提醒。编程难度苛刻。必须用非阻塞fdwhile循环读至EAGAIN否则残留数据会静默丢失导致响应超时。性能开销极高。大幅减少无效唤醒次数高并发下CPU和吞吐量表现最优(Nginx的看家本领)适用场景极致性能场景需处理海量连接且对延迟敏感(如游戏网关、高频交易)

相关新闻

C++实现通胀挂钩债券交换测试:量化金融建模与实战

C++实现通胀挂钩债券交换测试:量化金融建模与实战

1. 项目概述:从量化视角看债券交换最近在整理一些过往的量化策略研究笔记,翻到了一个挺有意思的实践项目:用C实现一个针对通胀挂钩债券(CPI-Linked Bond)的交换(Swap)测试实例。这个项目源于几年…

2026/10/15 16:09:58 阅读更多 →
Modbus协议详解与工业自动化应用实战

Modbus协议详解与工业自动化应用实战

1. Modbus协议入门:电气工程师的必修课 第一次接触Modbus时,我正面对着一台死活不通讯的变频器。屏幕上闪烁的"通讯超时"让我意识到,这个看似简单的协议背后藏着不少门道。Modbus作为工业自动化领域最常用的通讯协议之一&#xff0…

2026/10/11 10:14:51 阅读更多 →
Remix IDE入门:10分钟掌握智能合约开发全流程

Remix IDE入门:10分钟掌握智能合约开发全流程

1. Remix IDE快速入门:智能合约开发全流程解析 作为以太坊智能合约开发的瑞士军刀,Remix IDE让开发者能在浏览器中完成从编写到部署的全流程。这个基于Web的集成开发环境特别适合快速验证想法和教学演示,今天我们就用10分钟走通智能合约的完整…

2026/10/9 15:04:34 阅读更多 →

最新新闻

RISC-V E300时钟系统详解:PLL配置与低功耗设计

RISC-V E300时钟系统详解:PLL配置与低功耗设计

调过的板子里,十个有八个“看起来是软件问题”的怪毛病,最后都能在时钟树上找到根源。UART出来全是乱码,SPI时序对不上,PWM频率差一大截——第一反应怀疑代码,第二反应怀疑信号完整性,折腾一圈回头才发现&a…

2026/10/15 16:51:56 阅读更多 →
LangGraph 初学者入门文档1

LangGraph 初学者入门文档1

结论先行 LangGraph 是一个用于构建有状态、可控的 AI Agent 工作流的编排框架。它把 Agent 的逻辑建模成一张图——节点负责干活,边负责控制流程,状态在整张图中流动。对于初学者,建议从最小的“单节点线形图”开始,逐步加入条件…

2026/10/15 16:51:56 阅读更多 →
MQTT QoS深度解析:报文交换机制与选型建议

MQTT QoS深度解析:报文交换机制与选型建议

1. 从一次实际故障聊起:为什么选错 QoS 会让人半夜爬起来修 先说个我踩过的坑。某次给一套物联网设备做数据采集,传感器每隔几秒上报一次温湿度,我图省事把所有消息都设成了 QoS 0,觉得"丢了就丢了,下一条马上就来…

2026/10/15 16:51:56 阅读更多 →
35kV单侧电源辐射网三段式电流保护整定计算与仿真验证

35kV单侧电源辐射网三段式电流保护整定计算与仿真验证

前段时间帮朋友做一套35kV单侧电源辐射网的继电保护整定方案,核心就是经典的三段式电流保护。说实话,这套东西教材上讲得不少,但真正从短路电流计算、逐段整定、灵敏度校验、时限配合一路做到仿真验证,里面值得抠的细节远比想象中…

2026/10/15 16:51:56 阅读更多 →
OpenClaw 3.1.0 下载安装教程,快速搭建本地 AI 数字员工

OpenClaw 3.1.0 下载安装教程,快速搭建本地 AI 数字员工

Windows 一键部署 OpenClaw 教程|5 分钟搞定本地 AI 智能体,告别复杂配置 说明:本文适配 CSDN 发布,全部版本号、链接、文件大小已替换,删除标签 / 日期 / 阅读量 / 示意图,规避禁用词汇,首次全…

2026/10/15 16:51:56 阅读更多 →
SVC与NuSVC选型指南:C参数vs nu参数的工程决策逻辑

SVC与NuSVC选型指南:C参数vs nu参数的工程决策逻辑

简介:本资源是一份面向Python数据挖掘初学者与机器学习实践者的SVM分类模型详解文档,聚焦scikit-learn中三种核心支持向量机实现——SVC、NuSVC与LinearSVC的原理对比、参数含义及完整可运行代码示例。文档以鸢尾花、二维人工数据等典型场景为载体&#…

2026/10/15 16:50:56 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →