服务器接高性能,高性能服务器——I/O多路转接的三种模式(select &poll& epoll)

一、简单的服务器I/O模型

最简单的的TCP服务器,有三种模式:

1、单执行流,一个server端连接一个client端

2、多进程,一个server端通过多进程的方式,每个进程连接一个client端

3、多线程,一个server端通过多进程的方式,每个线程连接一个client端

要提升服务器性能,其实就是想要让一个server端能在负载允许的情况下,连接尽可能多的client端。

因此,以上三种模式中:

第一种模式,一个服务器连接一个客户端  ~!@#%……   这是低性能服务器 是没人会考虑的

第二种模式,用多进程,能同时服务多个client端,不过线程开销较大,因此这也不是最好的方式

第三种模式,用多线程,线程的开销比进程要小,因此这种方式是 这三种方式中,最优的方式。

二、所谓高性能

我们仔细分析第三种模式下,server端每个线程和对应连接的client在进行通信的过程中,其实都是阻塞方式的。

也就是,对于server端的每个线程,在对面客户端端有消息的时候(连接、接受、断开时)进行处理,而当对面没有消息过来的时候,则一直等待。

因此,在这种阻塞模式下,这些等待的时间被白白浪费掉了。归根到底,每个线程也只能服务一个客户端,因此还不够高性能。要想提高性能,就是要尽可能减少等待时间,也就是说,服务器最高效的工作状态是: 在能力范围内一直在进行数据搬迁。

要想进一步提升服务器性能,达到上述的工作状态,条件允许时(大部分情况都是如此)自然需要换一种效率更高的I/O模型,这里有以下模型://1、非阻塞I/O;

//2、I/O复用

//3、信号驱动I/O

//4、异步I/O

以上在这些模型当中,效率最高的当属第二种:I/O复用模型。

关于I/O复用,客官且听我慢慢道来

三、所谓I/O复用

I/O复用,是针对一个单线程而言的,采用I/O复用的server端,一个线程就可以处理多个client端。

它的实现,就好像有一个"管家",这个"管家"被托管了许多个套接字。当有新的client端要连接的时候,把这个client端(的句柄)托管给这个“管家”,所以这个“管家“上很有可能被托管了许多个client端。

管家的任务就是:管理他托管的这些套接字,如果这些套接字有消息传来,就通知server。

而server则平时一直等待它的"管家",直到"管家"告诉它有消息,才做相应的处理。

这样,server端的一个线程,就能同时服务许多client端,相比多线程模型,线程用来等待时间的比例明显低了很多,效率也高了许多。

要实现I/O复用,有三种模式:分别是: select、poll、epoll,以下分别介绍。

三、I/O复用——select 和 poll

别看poll 和 epoll 名字就差一个e,但其实 poll 和 select 更像,所以这里就把这两个模型放在一起介绍了。

(1)、select模式

还记得前面说到的那个"管家"吗?现在这里管家就是select,管家有一个(或多个)名单fd,fd上记录着所有被托管着的句柄。

//fd是一个fd_set类型的变量。fd_set中存放的句柄,都是通过位运算的方式存放的。

select模式,用到的函数有这些:int select(int nfds, fd_set *readfds, fd_set *exceptfds, struct timeval *timeout);

void FD_CLR(int fd, fd_set *set);

int  FD_ISSET(int fd, fd_set *set);

void FD_SET(int fd, fd_set *set);

void FD_ZERO(fd_set *set);

(2)、poll模式

原文:http://zhweizhi.blog.51cto.com/10800691/1832644

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值