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

手机网站字体自适应做网站 二维码登录

手机网站字体自适应,做网站 二维码登录,如何查看网站服务器,品质好的英文《UNIX网络编程卷1:套接字联网API》第6章 I/O复用:select和poll函数 6.1 I/O复用的核心价值与适用场景 I/O复用是高并发网络编程的基石,允许单个进程/线程同时监控多个文件描述符(套接字)的状态变化,从而高…

《UNIX网络编程卷1:套接字联网API》第6章 I/O复用:select和poll函数


6.1 I/O复用的核心价值与适用场景

I/O复用是高并发网络编程的基石,允许单个进程/线程同时监控多个文件描述符(套接字)的状态变化,从而高效处理多个客户端请求。其核心价值在于:

  • 资源高效利用:避免为每个连接创建独立线程/进程的内存与调度开销;
  • 事件驱动模型:仅在数据可读/可写时触发处理逻辑,减少空转;
  • 实时性保障:及时响应多个连接的并发事件。

典型应用场景

  • Web服务器(如Nginx):处理数千并发HTTP连接;
  • 实时通信系统(如IM):同时管理多个客户端的长连接;
  • 嵌入式网关:资源受限设备中处理多路传感器数据。

6.2 select函数深度解析
6.2.1 select函数原型与参数
#include <sys/select.h>int select(int nfds, fd_set *restrict readfds,fd_set *restrict writefds,fd_set *restrict exceptfds,struct timeval *restrict timeout);

参数详解

  1. nfds:需监控的最大文件描述符+1(优化内核遍历效率);
  2. readfds/writefds/exceptfds:分别监控可读、可写、异常事件的文件描述符集合;
  3. timeout:超时时间(NULL为阻塞,0为非阻塞,>0为限时等待)。

返回值

  • >0:就绪的文件描述符总数;
  • 0:超时无事件;
  • -1:错误(如被信号中断)。
6.2.2 文件描述符集合操作宏
void FD_ZERO(fd_set *set);       // 清空集合
void FD_SET(int fd, fd_set *set);// 添加描述符到集合
void FD_CLR(int fd, fd_set *set);// 从集合移除描述符
int FD_ISSET(int fd, fd_set *set);// 检查描述符是否就绪
6.2.3 select工作流程
  1. 初始化集合:使用FD_ZEROFD_SET设置需监控的描述符;
  2. 调用select:阻塞或等待事件发生;
  3. 遍历检查:通过FD_ISSET轮询所有描述符,处理就绪事件;
  4. 重置集合:select会修改传入的集合,需在每次调用前重新初始化。

代码示例:基于select的TCP服务器框架

fd_set read_set, all_set;
int maxfd = listenfd; // 监听套接字
FD_ZERO(&all_set);
FD_SET(listenfd, &all_set);for (;;) {read_set = all_set; // 每次select调用前重置集合int nready = select(maxfd + 1, &read_set, NULL, NULL, NULL);if (FD_ISSET(listenfd, &read_set)) { // 新连接到达int connfd = Accept(listenfd, NULL, NULL);FD_SET(connfd, &all_set);maxfd = (connfd > maxfd) ? connfd : maxfd;}for (int fd = listenfd + 1; fd <= maxfd; fd++) { // 检查客户端连接if (FD_ISSET(fd, &read_set)) {// 处理客户端请求(如read/write)}}
}
6.2.4 select的局限性
  1. 文件描述符上限FD_SETSIZE(通常1024)限制最大监控数量;
  2. 线性扫描效率低:每次需遍历所有描述符,时间复杂度O(n);
  3. 内核态内存复制:每次调用需将集合从用户态复制到内核态;
  4. 无法动态扩展:无法在运行中添加/移除描述符,需重新初始化集合。

6.3 poll函数:改进的I/O复用机制
6.3.1 poll函数原型与参数
#include <poll.h>int poll(struct pollfd *fds, nfds_t nfds, int timeout);

参数解析

  1. fds:指向pollfd结构数组,每个元素描述一个监控的描述符;
  2. nfds:数组长度(即监控的描述符数量);
  3. timeout:超时时间(毫秒,-1为阻塞,0为非阻塞)。

pollfd结构体

struct pollfd {int   fd;       // 文件描述符short events;   // 监控的事件(POLLIN、POLLOUT等)short revents;  // 返回的事件(由内核填充)
};
6.3.2 poll事件标志
  • POLLIN:数据可读(包括TCP连接断开时的EOF);
  • POLLPRI:紧急数据可读(如TCP带外数据);
  • POLLOUT:数据可写;
  • POLLERR:错误发生(自动监控,无需设置);
  • POLLHUP:连接挂起(如对端关闭)。
6.3.3 poll工作流程
  1. 初始化pollfd数组:设置每个元素的fdevents
  2. 调用poll:等待事件发生;
  3. 遍历检查revents:处理就绪的描述符;
  4. 动态维护数组:可动态添加或移除描述符。

代码示例:基于poll的TCP服务器框架

#define MAX_CLIENTS 1024
struct pollfd client_fds[MAX_CLIENTS];
int nfds = 1; // 初始只有监听套接字client_fds[0].fd = listenfd;
client_fds[0].events = POLLIN;for (;;) {int nready = poll(client_fds, nfds, -1);if (client_fds[0].revents & POLLIN) { // 新连接到达int connfd = Accept(listenfd, NULL, NULL);client_fds[nfds].fd = connfd;client_fds[nfds].events = POLLIN;nfds++;}for (int i = 1; i < nfds; i++) { // 遍历客户端连接if (client_fds[i].revents & POLLIN) {// 处理客户端请求if (read返回0) { // 客户端关闭连接Close(client_fds[i].fd);client_fds[i] = client_fds[nfds-1]; // 数组末尾元素覆盖当前nfds--;i--; // 重新检查当前位置}}}
}
6.3.4 poll的优势与不足

优势

  • 无描述符数量限制:仅受系统资源约束;
  • 动态管理:可随时添加/移除监控的描述符;
  • 更精细的事件控制:支持更多事件类型(如带外数据)。

不足

  • 仍为线性扫描:时间复杂度O(n);
  • 水平触发模式:未处理事件会持续通知(可能引起忙等)。

6.4 select与poll对比分析
特性selectpoll
描述符上限FD_SETSIZE(通常1024)仅受系统限制
事件类型仅读、写、异常支持更多事件(如POLLPRI)
效率低(O(n)遍历)低(O(n)遍历)
内存拷贝每次调用需复制整个集合仅传递数组指针
可扩展性静态集合,需重新初始化动态数组,可随时修改
跨平台兼容性所有UNIX系统多数UNIX系统(Linux、BSD)

选型建议

  • 嵌入式系统:优先poll(动态管理更灵活);
  • 高并发场景:推荐epoll(第7章详解);
  • 跨平台需求:select兼容性更好。

6.5 性能优化与陷阱规避
6.5.1 select性能优化
  1. 减少nfds值:仅传递当前最大描述符+1;
  2. 分离监控集合:将频繁活动的描述符单独监控;
  3. 避免阻塞操作:在事件处理函数中使用非阻塞I/O。
6.5.2 poll常见陷阱
  1. 未重置revents:每次调用poll前需清空revents或重新初始化结构体;
  2. 数组越界:动态添加描述符时需检查数组上限;
  3. 忽略POLLHUP:未处理可能导致死循环。

代码示例:非阻塞read处理

// 设置套接字为非阻塞
int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);char buf[1024];
ssize_t n = read(fd, buf, sizeof(buf));
if (n > 0) {// 处理数据
} else if (n == 0) {// 对端关闭连接
} else if (errno == EAGAIN || errno == EWOULDBLOCK) {// 数据未就绪,继续监控
} else {// 其他错误处理
}

6.6 实战:基于select的聊天服务器
6.6.1 功能需求
  • 支持多客户端连接;
  • 客户端消息广播至所有其他客户端;
  • 客户端退出时自动清理资源。
6.6.2 核心代码实现
#include "unp.h"#define MAX_CLIENTS 1024
int client_fds[MAX_CLIENTS];void broadcast(int sender_fd, char *msg, int len) {for (int i = 0; i < MAX_CLIENTS; i++) {if (client_fds[i] != -1 && client_fds[i] != sender_fd) {Writen(client_fds[i], msg, len);}}
}int main() {int listenfd = Socket(AF_INET, SOCK_STREAM, 0);// 绑定与监听(代码同前)fd_set all_set, read_set;FD_ZERO(&all_set);FD_SET(listenfd, &all_set);int maxfd = listenfd;memset(client_fds, -1, sizeof(client_fds));for (;;) {read_set = all_set;int nready = select(maxfd + 1, &read_set, NULL, NULL, NULL);if (FD_ISSET(listenfd, &read_set)) {int connfd = Accept(listenfd, NULL, NULL);// 将新连接加入数组for (int i = 0; i < MAX_CLIENTS; i++) {if (client_fds[i] == -1) {client_fds[i] = connfd;FD_SET(connfd, &all_set);maxfd = (connfd > maxfd) ? connfd : maxfd;break;}}}for (int i = 0; i < MAX_CLIENTS; i++) {int fd = client_fds[i];if (fd == -1) continue;if (FD_ISSET(fd, &read_set)) {char buf[1024];ssize_t n = Read(fd, buf, sizeof(buf));if (n > 0) {broadcast(fd, buf, n);} else {Close(fd);FD_CLR(fd, &all_set);client_fds[i] = -1;}}}}
}

6.7 调试工具与性能分析
6.7.1 使用strace跟踪系统调用
strace -e select,poll,read,write ./server

输出示例

select(5, [3 4], NULL, NULL, NULL) = 1 (in [3])
read(3, "hello", 1024)             = 5
6.7.2 监控文件描述符状态
# 查看进程打开的文件描述符
ls -l /proc/<pid>/fd
6.7.3 性能压测工具
# 使用netcat模拟多客户端
for i in {1..1000}; donc 127.0.0.1 9999 &
done

6.8 本章小结与进阶习题

小结:本章深入解析了select和poll的原理、使用场景与优化技巧,通过实战案例展示了高并发服务器的实现方法。

习题

  1. 实现基于poll的聊天服务器,支持昵称注册与私聊功能;
  2. 对比select与poll在1000并发连接下的CPU使用率差异;
  3. 扩展select服务器支持可写事件监控,实现大文件传输。

说明

  1. Linux下更详细select函数内容,可参见博主相关博文Linux下select使用
  2. 嵌入式下如何高效使用select与epoll,可参见博主相关专题博文在嵌入式Linux中实现高并发TCP服务器:从select到epoll的演进与实战
  3. Linux下更详细epoll函数内容,可参见博主相关博文Linux下epoll函数使用详解

付费用户专属资源

  • 完整聊天服务器代码工程(含Makefile);
  • select/poll性能对比测试报告;
  • 扩展阅读:《从select到epoll:Linux I/O模型的演进》。

通过本章学习,读者将掌握I/O复用的核心技术,并能够开发高并发的网络应用。


文章转载自:

http://2yqTWFwx.nypgb.cn
http://0jvOKzel.nypgb.cn
http://eVdiCXHW.nypgb.cn
http://XXmXQ744.nypgb.cn
http://VS7gauU0.nypgb.cn
http://vuxc2kq3.nypgb.cn
http://BEFqg4Fm.nypgb.cn
http://4FVXJSYb.nypgb.cn
http://hL8ZkpJO.nypgb.cn
http://8pqWrkeO.nypgb.cn
http://ZItXm5rM.nypgb.cn
http://9CAVtcM7.nypgb.cn
http://mvQ7uYty.nypgb.cn
http://Tw2Z21Ul.nypgb.cn
http://MGPNP0OS.nypgb.cn
http://DITzGsRJ.nypgb.cn
http://Da7Y2Pm9.nypgb.cn
http://4He4LqqS.nypgb.cn
http://UQQnP3MN.nypgb.cn
http://TE6oFLrg.nypgb.cn
http://WRNNt5Nj.nypgb.cn
http://y0wjbsnT.nypgb.cn
http://iVqcgADJ.nypgb.cn
http://DfdbTOho.nypgb.cn
http://WGLg8Gry.nypgb.cn
http://hjPWIMZU.nypgb.cn
http://mgW9SLq7.nypgb.cn
http://sAJXRfZK.nypgb.cn
http://aLUHiOlW.nypgb.cn
http://Ap2GMyoH.nypgb.cn
http://www.dtcms.com/wzjs/658353.html

相关文章:

  • wordpress前端文章编辑器南宁企业官网seo
  • 东营专业网站建设公司电话昆明网上房地产官网
  • 网站程序开发要点企业qq官网
  • 万户信息 做网站怎么样网站开发经营范围
  • 做网站需要 的文档网络运营公司排名
  • 企业网站登录入口官网开发公司赠送阁楼视同销售
  • 做网站推广员图片处理问题加工平台苏州纳米所
  • 网站模块在线制作万网域名注册网站
  • 个人如何办网站网站搭建网站管理
  • 三丰云怎么做网站西安观止软件科技有限公司
  • 广州天与地网站建设公司网站服务器租赁
  • 大型公司为什么做网站网站建设上传图片不显示
  • 网站备案主体是什么意思潍坊网站建设教程
  • 个人电脑搭建成网站服务器做试用网站的原理
  • 网站如何吸引蜘蛛html5单页面网站建设
  • 教学网站前台模板个人可以做社区网站有哪些
  • 安徽网站推广优化济南城市建设职业学院官网招生网
  • 寻找项目做的网站装饰工程经营范围有哪些
  • 国内手机网站建设美术培训学校网站模板
  • element ui设计网站中企动力公司网站价格
  • 装饰网站设计模板wordpress新建页面显示数据
  • 网站代码在哪里看智能城市 电子商务网站建设
  • 做网站设计的价格wordpress音乐主题
  • 西安做企业网站秦皇岛哪有网站优化公司
  • 贵州建设厅报名登录网站宁波网站建设seo
  • 社交网站 ui兴安盟住房和城乡建设部网站
  • 网络设计网站网站刚通过备案
  • 怎么查看一个网站的后台淄博市住房和城乡建设厅网站
  • 网站使用什么数据库搭建专业网站服务器
  • 贵州做网站的如何对网站做优化