并发程序设计2:多路IO复用技术

  上一节https://www.cnblogs.com/yuanwebpage/p/12361275.html记录了多进程并发程序,除了已经描述的缺点,考虑服务器端一直在调用accept函数结束客户端请求,所以没办法进行其他响应,如响应用户的输入/输出。而多路IO复用除了能同时执行一种IO的多个操作,还能响应不同类IO的操作。

1. 基于select的IO复用

  select的IO复用原理很简单。每个文件描述符在Linux系统下就是一个整数,比如现在有4个应用客户端与服务器建立连接,其套接字分别为fd0,fd1,fd2,fd3,select的原理就是将这些套接字集中起来管理,采用fd_set数组,fd_set数组每一位代表一个套接字状态,当把fd0,fd1,fd2,fd3装入fd_set时,其状态如图1.1所示

                                                                       

                                                                            图1.1 select函数管理的fd_set数组

将某个套接字添加到fd_set数组后,将其全部置0。调用select函数时,发生事件(如fd2的套接字接收到客户端发来的消息),对应的数组位就会从0变成1,此时检测fd_set数组中从0变成1的那些位,就是发生变化的描述符。因此,使用select函数流程如下:

(1) 设置文件描述符,即声明fd_set变量;

(2) 将要监视的描述符加入fd_set数组;

(3) 将数组清零;

(4) 设置超时时间(select函数是阻塞型的,因此设置超时时间,超时还没有fd_set数组变化就返回);

扫描二维码关注公众号,回复: 9401234 查看本文章

(5) 调用select,监视变化,并进行后续处理。

下面看select函数的具体用法

#include <sys/select.h>

int select(int maxfd, fd_set* readset, fd_set* writeset, fd_set* exceptset, const struct timeval* timeout);

maxfd:监视的文件描述符个数
readset:记录“是否存在待读取的文件描述符”的变量
writeset:记录“是否存在待写的文件描述符”的变量
exceptset:记录所有异常的文件描述符的变量,
timeout:设置超时的结构体
struct timeval
{
    long tv_sec; //
    long tv_usec;  //毫秒
}

关于fd_set的添加,清零,检测变化的函数如下:

FD_SET(int fd, fd_set* fdset); //将文件描述符fd注册到fdset中
FD_CLR(int fd, fd_set* fdset); //将文件描述符fd从fdset中删除
FD_ZERO(fd_set* fdset);  //将fdset清零
FD_ISSET(int fd, fd_set* fdset);  //判断fd是否发生变化,即是否有事件来临

有了以上基础知识,现在将

猜你喜欢

转载自www.cnblogs.com/yuanwebpage/p/12362876.html