poll&epll 模型

POLL网络编程模型

PIPE信号的产生与处理,如何减少time_wait。

1.首先是创建socket,设置ip端口。(socket_nonbock,socket_closexec)每个socket都有自己的输入缓冲区和输出缓冲区。

2.再是设置端口复用,绑定端口,监听端口。

3.定义poll event结构和events数组,将监听的事件的描述符加到poll event中,并且监听pollin事件。

poll event{
 int fd;
 fd* evnet//监听的事件
 fd* revent //返回的事件
}

4.调用poll函数poll(pollfd,events,timeout),将会返回所有的events事件,不管他们有没有发生pollin事件;

5.处理events[0].revent。第一个描述符有事件到来,那么说明有新的连接过来,将其加入到events列表中。

那么这里有一种情况,如果系统的文件描述符用完了怎么办?可以采用打开一个空文件的办法来解决。如果打开文件描述符失败,系统会返回emifle事件,如果产生了这个事件,就关闭打开的空文件,再accept,打开新建立的文件描述符,再关闭这个描述符。再打开空文件,以备下次使用。这样是为了避免产生阻塞。

6.如果监听的连接中有了pollin事件,则开始接受数据。接收数据后再把输出结果写到内核缓冲区(回射服务器)。那什么时候监听pollout事件呢?当要写的数据大于内核缓冲区的时候则是需要监听pollout事件。

当要返回的数据大于内核缓冲区的时候,等到把内核缓冲区写满以后,需要将剩余的数据暂时放到用户空间的缓冲区内,并且监听pollout事件,当发生pollout事件后,说明内核输出缓冲区已经空闲出来了,此时可以继续往内核输出缓冲区里写入数据,就这样直到把要发送的数据发送完为止。

 

EPOLL网络编程模型

epoll分了水平触发模式和边缘触发模式,水平触发模式和poll是相同的(高电平有效)。

水平触发:当输入缓冲区中有数据时,处于高电平,pollin事件是一直有效的。如果数据全部被处理了,则由高电平转到低电平,此时才没有epollin事件。

epollout事件则是当内核缓冲区的数据被读走时才会触发,如果没被写满就会一直保持在高电平,这使得在一开始不能监听此事件,否则会陷入busy loop。

边缘触发则是不同:

epollin事件是在接收缓冲区没有数据->接收缓冲区有数据时触发,(由低电平->高电平),此时可以读到epollin事件,必须处理。这个特性使得处于边缘触发时必须要一次读完缓冲区中的数据,否则的话即使下次再有数据过来也不会触发epollin事件。

epollout事件则是在内核缓冲区数据被读走时才触发,这个特性使得可以在一开始监听此事件。

ET模式下,EPOLLOUT触发条件有:

1.缓冲区满-->缓冲区非满;

2.同时监听EPOLLOUT和EPOLLIN事件 时,当有IN 事件发生,都会顺带一个OUT事件;

3.一个客户端connect过来,accept成功后会触发一次OUT事件。

当设置监听事件后,内核就会依次遍历各个描述符,如果发生了监听事件,就把它添加到事件队列里,没有则继续轮询,直至超时。

 

使用epoll,1g内存大概可以承载10万连接。由于使用epoll开销较大,在连接数量不多,信息量少,且连接活跃的情况下性能还不如poll与select。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值