网络IO复用模型
1.poll(epoll中的LT模式,电平触发模式)poll不支持边沿触发
说明 监听套接字应该设置为非阻塞模式,否则会影响服务器的并发性
ret是成功写入的数据大小,10000是想要写入的数据大小
应该使用下右下角的连接套接字处理过程
当数据包比较大时,一个数据包要进行两次read,一次read并没有把connfd所对应的接收缓冲区的数据都读完,那么connfd仍然是活跃的,我们应该将读到的数据保存在connfd的应用层接收缓冲区
write发送时,我们也应该有一个应用层发送缓冲区
POLLOUT事件 触发条件,connfd的发送缓冲区不满(可以容纳新数据)//【不应该一开始就关注pollout事件,因为一开始缓冲区没数据发送它会一直触发pollout事件,会出现busyloop忙等待,所以在if(ret<10000)的条件下才关注pollout事件,当应用层发送缓冲区数据发送完毕后也应取消关注pollout事件】
2.EMFILE错误的处理
accept(2)返回EMFILE(进程打开的文件描述符的个数超出了上限)的处理:
调高进程文件描述符个数//治标不治本
死等//影响效率
退出程序//??不可以 7*24小时工作
关闭接听套接字//那啥时候再打开嗯?
如果是epoll模型,可以改用edge trigger,问题是如果漏掉了一次accept(2),程序在也不会收到新连接
准备一个空闲的描述符。遇到这种情况,先关闭这个空闲文件,获得一个文件描述符名额,再accept(2)拿到socket连接的文件描述符;随后立刻close(2),这样优雅的断开了与客户端的连接;最后重新打开空闲文件,把坑填上,以后再出现这种情况时再使用。//可以,所以一般用这种
3.epoll
分为LT电平触发模式,与poll模式类似,但是不需要遍历所有已连接套接字模型,只需遍历活跃的
ret=0说明对方关闭了套接字,那么需要将此套接字剔除
poll与epoll:
每次调用poll函数时都需要把监听套接字与已连接套接字所感兴趣的时间数组 拷贝到内核,这样会导致效率降低,
epoll模型只需拷贝一次
LT 什么时候关注pollout事件,如果接受到一个新的套接字就关注pollout事件的话就会造成busy loop
ET边缘触发模式,默认是LT,如果改成ET,将events成员改为EPOLLIN
epoll_create(int size)//size能够管理的系统文件描述符的数目,这个参数已经被忽略了,因为取决于系统资源的大小,即处理多大的并发
epoll_create1(int flags)//
3.2ET模式
ET一开始就关注poll out事件也不会触发busyloop,一直处于可发送状态
边沿触发从高到底或者从低到高才会触发,等缓冲区数据已经满了不可发送数据到可发送数据期间才触发epollout事件
缓冲区从低到高才会触发epollin事件
read要读到EAGAIN为止才可以,否则电平不会变不会触发了