linux下的socket模型

来源:互联网 发布:js锚点跳转 编辑:程序博客网 时间:2024/05/22 12:26

-------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通讯。




0 0
原创粉丝点击