13 IO复用之select函数

Java NIO - IO多路复用 提供了非阻塞调用的方式,从操作系统层面解决了阻塞问题。将 socket 是否就绪检查逻辑下沉到操作系统层面,避免大量系统调用。告诉你有事件就绪,但是没告诉你具体是哪个 FD。epoll 直接将 fd 集合维护在内核中,通过红黑树来高效管理 fd 集合,同时维护一个就绪列表,当 fd 就绪后会添加到就绪列表中,当应用空间调用 epoll_wait 获取就绪事件时,内核直接判断就绪列表即可知道是否有事件就绪。 阅读详情

前面我们所有的代码都是通过read和write操作, 每次只能处理一个IO请求. 但是IO复用可以在同时处理多个socket的IO请求. 而且IO复用与线程连用是最常见的搭配.

本节介绍IO多路复用select函数.


函数原型

#include <sys/types.h>
#include <sys/times.h>
#include <sys/select.h>
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, 
			struct timeval *timeout);

成功 : 返回事件发生的个数, 并且将返回改变的文件符保存在对应的集合中.

失败 : 返回负数. 如果被中断不可重启, 会设置errno的值为EINTR.

超时 : 返回0.


函数参数

函数参数有点多, 可能一时间掌握不了可以慢慢做实验体验每个参数的意义.

  • nfds : 打开的最大文件描述符 + 1 (注意 : 是最大 + 1)
  • readfds : 读描述符集合
  • writefds : 写描述符集合
  • exceptfds : 错误描述符集合
  • timeout : 定时
    1. timeout == NULL : select函数永远阻塞等待监视文件描述符集合中某个文件描述符发生变化为止.
    2. timeout == 0 : 函数为非阻塞函数, 不管有无等待的文件描述符发生变化都会返回
    3. timeout > 0 : 等待的超时时间, 即函数在timeout时间内阻塞, 超时时间之内有事件到来就返回了, 否则在超时后不管怎样一定返回.

描述符集合

select函数有一个叫文件描述符集合的数据类型fd_set, fd_set很像信号集sigset_t而且两者的实现都很相似. sigset_t信号集有32位之多, 每一位表示一个信号. 同样fd_set描述符集默认有1024位(最大值用FD_SETSIZE表示), 每一位表示一个文件描述符.

sigset_t有一系列sigset函数, fd_set也同样有一系列的操作函数 :

// 从描述符集中删除fd
FD_CLR(int fd, fd_set *fdset);

// 清除描述符集所有设置的描述符
FD_ZERO(fd_set *fdset);

// 将fd添加到描述符集中
FD_SET(int fd, fd_set *fdset);

// 验证fd是否在描述符集中
FD_ISSET(int fd, fd_set *fdset);

函数调用

我们使用本节介绍的select函数来修改之前的代码, 实验验证与write函数的不同.

将客户端的代码做了修改, 这里只将修改的代码贴出分析. 完整的代码 select_client.c

// 客户端
int client(int port, const char *cli_addr)
{
    int sockfd;
    sockfd = Socket(0);
    Connect(sockfd, port, cli_addr);

    char buf[1024];
    int n;
	
    // 1
    fd_set rfds, testrfds;
    FD_ZERO(&rfds);
    FD_SET(sockfd, &rfds);
    FD_SET(STDIN_FILENO, &rfds);
    while(1)
    {
        // 2
		testrfds = rfds;
		if(select(sockfd + 1, &testrfds, NULL, NULL, NULL) < 0)
		    EXIT("select");
	
        // 3
		if(FD_ISSET(STDIN_FILENO, &testrfds))
		{
		    n = read(STDIN_FILENO, buf, sizeof(buf));
		    if(n == 0)
				break;
		    send(sockfd, &buf, strlen(buf), 0);
		}
        // 4
		if(FD_ISSET(sockfd, &testrfds))
		{
		    n = recv(sockfd, buf, sizeof(buf), 0);
		    if(n == 0)
				break;
		    write(STDOUT_FILENO, buf, n);
		}
    }
    close(sockfd);

    return 0;
}

需要注意几点

  1. 将新的描述符集zero再添加文件描述符
  2. 因为select返回会重置所有的描述符集, 所以必须将原描述符集保存下来, 并且每次循环都要重新设置
  3. 需要对每一个操作的描述符进行判断

最终运行的结果可以看出正常的回射任何问题, 并且服务端关闭后客户端立马也就关闭了.

在这里插入图片描述


总结

  • 掌握select函数的应用
  • 用select函数将服务器的多进程改成单进程的IO多路复用. 完整代码select_service.c.

参考

I/O多路复用技术(multiplexing)是什么?

Deepseek Engram 论文全面解读 以下是对 DeepSeek 与北京大学于联合发布的论文《》(简称Engram 论文)的。 阅读详情

相关推荐

激光三角测量法:斜射与直射式技术的原理与应用解析

本文深入解析激光三角测量法中斜射式与直射式技术的原理、应用及对比。斜射式适用于高精度小范围测量,尤其擅长处理反光表面;直射式则适合大范围位移检测,结构更简单。文章详细介绍了两种技术的光路分析、数学建模、应用场景及选型建议,并探讨了系统校准与误差分析方法,为工业检测领域提供实用参考。

weixin_29280219的博客 413

IO多路复用之select

本文讲解了IO多路复用,详细的讲解了select函数,并通过select实现了select服务器程序实例让大家深入了解了select多路复用,希望这篇博客可以让大家有所收获。

qq_52836452的博客 2368

MatterPort3D 数据集下载

【代码】MatterPort3D 数据集下载。

qq_44106838的博客 6770

IO多路复用——select

Linux Socket网络编程——IO多路复用select

PANTAN_优快云的博客 1390

echarts如何实现3D饼图(环形图)?

自定义修改3D饼图的宽高和legend

i-cat的博客 1万+

Autodesk激活无无网络选项?许可类型与脱机激活排查修复指南

软件许可激活是保障正版授权正常使用的核心环节,常见的授权模式包括单机版许可和网络版许可,两者在认证机制和应用场景上有所区别。单机版离线授权依托 FlexNet Licensing Service 等底层服务组件,在断网或内网环境下为用户提供可靠的技术支持与授权验证路径。然而在实际部署中,激活窗口并不总是显示“无网络激活方式”入口,这可能与许可类型选择、网络环境干扰、组件安装残留或系统时间偏差有关。理解入口的动态呈现逻辑与排查顺序,有助于在 AutoCAD、Revit 等 Autodesk 产品中高效解决脱机

weixin_28709649的博客 355

IO复用之select

select()函数和pselect()函数都用于用于IO复用,它们监视多个文件描述符的集合,判断是否有符合条件的事件发生。 select()函数与recv()函数和send()函数不同的是,recv()函数和send()函数可直接操作文件的描述符。但是使用select()函数时,需要先对所要操作的文件描述符进行查询,查看目标文件的描述符是否可以进行读、写、或...

jiaomubai的博客 2327

第4章-上下文管理-对话历史记忆系统与窗口优化-《Agentic AI 智能体应用开发》

当上下文窗口接近极限时,需要对已有内容进行压缩。压缩不是简单的截断——你需要保留核心语义,去除冗余。# Python: 对话摘要压缩# 使用 Haiku 做摘要任务,成本最低"""将一段对话历史压缩为摘要"""system="你是一个对话摘要专家。请生成简洁但有信息量的摘要。",f"'用户'

AI天才研究院 245

IO多路转接(复用)之select

rdset用于保存要检测的原始数据,这个变量不能作为参数传递给select函数,因为在函数内部这个变量中的值会被内核修改,函数调用完毕返回之后,里边就不是原始数据了,大部分情况下是值为1的标志位变少了,不可能每一轮检测,所有的文件描述符都是就行的状态。内核在遍历这个读集合的过程中,如果被检测的文件描述符对应的读缓冲区中没有数据,内核将修改这个文件描述符在读集合fd_set中对应的标志位,改为0,如果有数据那么这个标志位的值不变,还是1。这并不是巧合,而是故意为之。

yulindianzi的博客 307

家用扫地机器人实物拆解报告-从顶盖到每一颗螺丝 · 逐层拆解旗舰扫拖一体机器人

2026年旗舰扫拖机器人拆解报告:采用D形机身设计,主机重4.5kg,基站重12kg。核心配置包括RK3588S+STM32H743双处理器、8颗21700电池、LDS激光雷达和双摄像头+结构光导航系统。创新设计亮点:锥形滚刷自动排毛发、活水循环拖地系统、基站集成450W强力集尘和自动上下水模块(带三重防漏保护)。整机采用模块化设计,关键部件均支持快速更换,在密封性、防呆设计和降本增效方面展现出成熟的工程智慧。

智能硬件研发,欢迎交流 515

WiFi基本概念(六)(L-STF,L-LTF)

L-STF它由10个OFDM symbol(1,0,1,0,1,0,1,0,1,0)构成,每个symbol是0.8us,GI是0.2us,总计10us。Symbol的长度是正常长度的1/4,因此称为Short training field,主要用于快速进行信号检测,信号同步,自动增益控制,接收天线选择(Diversity Selection)。 由于symbol长度是正常的1/4,子载波的宽度是正常的4倍,能进行初略的信道估计,其使用了-24, -20, -16, -12, -8, -4, 4, 8, 1

reekyli的专栏 6860

【网络编程】IO 多路复用 select

文章以【网络编程】TCP socket 单机通信实验 为基础,尝试对 IO 多路复用 select 接口进行使用

_山月 2788

1、JMP脚本编程全面指南:从基础到高级应用

本博客全面介绍了JMP脚本编程的各个方面,从JMP基础和JSL入门,到数据类型、数据结构、编程方法、数据表操作、图形与三维场景脚本,再到应用程序创建与扩展功能。内容涵盖脚本工具使用、常见任务实现、兼容性说明及未来发展趋势,旨在帮助用户掌握JMP脚本语言的强大功能,提升数据分析的自动化与定制化能力。适合从初学者到高级用户的深入学习与实践参考。

flink9streamer的博客 266

【面试】彻底理解 IO多路复用

阅读本文大概需要 5 分钟。看完下面这些,高频面试题你都会答了吧目录1、什么是IO多路复用?2、为什么出现IO多路复用机制?3、IO多路复用的三种实现方式4、select函数接口5、se...

木川的技术之路 8257

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

[linux]IO多路复用机制:select、poll、epoll

​ 首先我要向大家输出一个IO的概念:IO在我看来就是 等 + 拷贝(简化IO模型),等就是等待系统资源(设备。数据等)就绪(比如等待文件描述符就绪,等待数据就绪),拷贝就是拷贝数据资源(比如将你写的把内容将它从写缓冲区拷贝到读缓冲区,让用户可以正常读取)。如果想要IO速度快,减少等待时间是提高IO性能的关键。等待时间通常包括等待硬件资源(如磁盘、网络)就绪的时间以及等待操作系统调度的时间。在IO密集型应用中,多个IO操作可能同时进行。减少每个操作的等待时间可以显著提高整体吞吐量,因为更多的操作可以在相同的

2202_75305885的博客 1316

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

IO复用,select,

一,IO复用的方法 IO复用的方法:select poll epoll IO复用的功能 这里的描述符就是套接字 以前TCP服务器端和客户端 一个服务器端要连接10个客户端就需要创建10个线程 学校发书,所有人在图书馆排队领书没到你你就在等相当于阻塞,另一种到你了我给你打电话你再来领就不会出现阻塞(例子) 在程序中来讲就是我们将所有要关注的描述符全部注册到select上,select帮我们检测哪个描述符上有数据产生(有可能是一个或2,3个上同时有数据) 举个例子来使用select 检测键盘(键盘也是描述符)

weixin_45510561的博客 820

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

13、SOCKET-IO复用技术 - select、poll、epoll

目录13、SOCKET-IO复用技术1、五种I/O模型2、阻塞I/O模型3、非阻塞I/O模型4、I/O复用模型5、信号驱动I/O模型6、异步I/O模型7、I/O复用8、shutdown函数9、select函数10、poll函数11、epoll函数11-1、epoll_create11-2、epoll_ctl11-3、epoll_wait11-4、Epoll工作模式11-5、epoll示例12、总结 13、SOCKET-IO复用技术 1、五种I/O模型 阻塞I/O 非阻塞I/O I/O复用(select和p

拒绝刘亦菲的博客 1717

聊一聊 .NET在Linux下的IO多路复用select和epoll

说了这么多,文尾总结下目前主流的 epoll 和 iocp 各自的特点。特性模型事件驱动 (Reactor)完成端口 (Proactor)核心思想通知可读写事件通知I/O操作完成适用场景高并发网络编程高并发I/O操作编程复杂度较低较高网络I/O性能极佳(百万级连接)优秀磁盘I/O支持有限完善CPU利用率高中内存开销低中。

qq_35485206的博客 936

柳大的Linux游记·基础篇(5)select IO复用机制

柳大的Linux游记·基础篇(5)select IO复用机制Author: 柳大·Poechant(钟超)Blog: blog.youkuaiyun.com/PoechantEmail: zhongchao.ustc#gmail.com (#->@)Date: March 13th, 2012Copyright © 柳大·Poechant1 基本原理注:select 原理图,摘自 IBM iSeries 信息

麦克船长的技术笔记 9263

18-IO多路复用 select

文章目录1. 1.

夏夜晚风_的博客 1123

掌握golang select IO多路复用

select作用 Go里面提供了一个关键字select,通过select可以监听channel上的数据流动。. select的用法与switch语言非常类似,由select开始一个新的选择块,每个选择条件由case语句来描述。 与switch语句相比,select有比较多的限制,其中最大的一条限制就是每个case语句后面必须是一个**Io操作** 。 大致的结构如下: select{ case <-chan1: //如果chan1成功读到数据,则进行该case处理语句 case ch

张成基 2万+

网络和Linux网络_13(高级IO+多路转接)五种IO模型+select编程

网络和Linux网络_13(高级IO+多路转接)五种IO模型+select服务器(IO钓鱼故事+阻塞IO+非阻塞IO+信号驱动IO+多路转接IO+异步IO+select编程完整代码+相关笔试选择题)

参考书籍:《C语言程序设计》《数据结构》《C++ Primer》《Effective C++》《STL源码剖析》《现代操作系统》《UNIX环境高级编程》《图解TCP/IP》《图解HTTP》《Linux高性能服务器编程》《剑指Offer》《算法导论》 1283

13. 高级IO

对于这个问题的答案,我们首先需要了解到,对于 mmap()函数来说,当文件成功被映射到内存区域时,这段内存区域(映射区)的大小通常是页大小的整数倍,即使参数 length并不是页大小的整数倍。另外,文件映射的内存区域的大小必须是系统页大小的整数倍,譬如映射文件的大小为 96 字节,假定系统页大小为 4096 字节,那么剩余的 4000 字节全部填充为 0,虽然可以通过映射地址访问剩余的这些字节数据,但不能在映射文件中反应出来,由此可知,使用存储映射 I/O 在进行大数据量操作时比较有效;

m0_63667883的博客 903
上一篇: 33.TCP异常之服务器中断
下一篇: 15. IO复用之poll函数
Function_18
博客等级 码龄10年 193粉丝 239原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值