linux下的socket模型

本文详细探讨了select、poll与epoll三种I/O多路复用技术的特点及应用场景。介绍了select监听文件描述符数量限制、使用注意事项;poll与select相似的性能表现;epoll高效的数据处理能力及推荐使用的LT模式等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

-------select

1.一个误区很多人认为它最大可以监听1024个,实际上却是文件描述符的值不能大于等于1024,所以除掉标准输入,输出,错误输出,一定少于1024个,如果在之前还打开了其他文件,那会更少

2.select返回后,一般要轮询fd_set,发现新的连接要加上,连接断开要去掉,这个过程一定要这样做:select之前把fd_set临时拷贝一份,轮询中对它的修改只在临时fd_set上做,轮询完了,再对这个临时fd_set select,否则你可能明明有连接进来,却accept不到,这可能是因为轮询中如果直接修改fd_set,select的底层就会定位错乱。

------poll

 性能测试发现,select与poll有相似的调用时间与CPU占有率,都随着数据量变大或者连接数变大(活动连接不变)而变大

连接进入时,返回POLLIN,连接关闭时返回POLLERR或者POLLIN

------epoll

正如传说的那样,epoll的调用时间与cpu占用率只随数据量变大,而几乎不受连接数影响

当连接关闭时,会收到EPOLLIN事件

在ET模式下,不管是监听socket还是连接客户端的socket,在EPOLLIN时,都应该重复read一直到EAGAIN(多次连接进入或者客户端的多次send调用都只产生一次EPOLL事件),否则下次等待EPOLLIN将会挂起,这样对上层应用处理起来更复杂

 所以还是推荐使用默认的LT模式

在对客户端的发送也可能出现阻塞,所以epoll也应该注册EPOLLOUT,但不是在一开始(那会让所有文件描述符都返回可用,降低epoll的效率,合理的机制应该是这样:对accept)的客户端连接一开始只注册EPOLLIN事件,触发后接收客户端消息,生成回复,将回复放到一个程序自己的缓冲区内,修改该文件描述符的注册事件为EPOLLIN|EPOLLOUT(视业务逻辑而定,如果要求必须应答发送之前不能接收请求,可只注册EPOLLOUT事件),当EPOLLOUT触发时,将回复发送出去,从缓冲区中删除回复,再修改该连接为EPOLLIN事件

即使在单线程程序中,在3万个连接的1万个活动连接上,epoll也可以一秒内收发100MB数据,所以如果没有其他的IO活动或则计算处理,单线程的epoll完全可以应付高并发socket通讯。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值