第十二章 I/O复用

来源:互联网 发布:苹果软件不可用 编辑:程序博客网 时间:2024/05/29 07:36

并发服务器的第二种实现方法-基于I/O复用Multi-plexing的服务器端构建。

 

1基于I/O复用的服务器端


多进程服务器端的缺点和解决办法

创建进程时需要付出极大代价,需要大量的运算和内存空间,每个进程具有独立的内存空间,所以相互间的数据交换也要求采用相对复杂的方法(IPC属于相对复杂的通信方法)

I/O复用能不创建进程的同时向多个客户端提供服务。


理解复用

在1个通信频道中传递多个数据(信号)的技术、

为了提供物理设备的效率,用最少的物理要素传递最多数据时使用的技术。

 

纸杯电话系统中引入复用优点:

减少连线长度;减少纸杯个数;

 


复用技术在服务器端的应用

服务器端引入复用技术可以减少所需进程数。


2 理解select函数并实现服务器端

运用select函数是最具代表性的实现复用服务器端方法。

 

select函数的功能和调用顺序

使用select函数时可以将多个文件描述符集中到一起同一监视,项目如下

是否存在套接字接收数据?

无需阻塞传输数据的套接字有哪些?

哪些套接字发生了异常?

 

监视项称为“事件”。发生监视项对应情况时,称“发生了事件”。

 

select函数的调用方法和顺序

步骤一:设置文件描述符指定监视范围设置超时

步骤二:调用select函数

步骤三:查看调用结果

 

设置文件描述符

利用select函数可以同时监视多个文件描述符,监视文件描述符可以视为监视套接字。首先将需要监视的文件描述符集中到一起。集中时也要按照监视项(接收、传输、异常)进行区分,即按照上述3种监视项分为3类。

使用fd_set数组变量执行,数组是存有0和1的位数组。0的时候表示文件描述符0所在位置,1表示该文件描述符是监视对象。

针对fe_set变量的操作是以位为单位进行的,意味着直接操作该变量会比较繁琐。在此变量中注册或更改值的操作由下列宏完成。


FD_ZERO(fd_set *fdset);//将fd_set变量的所有位初始化为0   FD_SET(int fd,fd_set *fdset);//在参数fdset指向的变量中注册文件描述符fd的信息   FD_CLR(int fd,fd_set *fdset);//在参数fdset指向的变量中清除文件描述符fd的信息   FD_isset(int fd,fd_set *fdset);//若参数fdset指向的变量中包含文件描述符fd的信息,则返回真


设置检查(监视)范围及超时

#include<sys/select.h>  #include<sys/time.h>  int select(int maxfd,fd_set * readset,fd_set * writested,fd_set * exceptset,const struct timeval * timeout);
成功时返回大于0的值,失败时返回-1.

maxfd:监视对象文件描述符数量
readset:将所有观注“是否存在待读取数据”的文件描述符注册到fd_set变量,并传递其地址值 
writested将所有观注“是否可传输无阻塞数据”的文件描述符注册到fd_set变量,并传递其地址值
exceptset将所有观注“是否发生异常”的文件描述符注册到fd_set变量,并传递其地址值
timeout:调用函数后,为防止陷入无限阻塞状态,传递超时信息

 

文件描述符的监视范围与select函数的第一个参数有关。

select函数的超时时间与函数的最后一个参数有关,其中timeval的结构体定义如下


struct {  long tv_sec;  long tv_usec;  }

调用select函数后查看结果

select函数如果返回大于0的整数,说明相应数量的文件描述符发生变化。P201~P203






原创粉丝点击