第七篇 网络IO模型

IO(Input/Output,输入输出)有两种操作,同步IO和异步IO;网络中的IO由一下四种情况:

  • 输入操作:等待数据到达套接字接收缓冲区;
  • 输出操作:等待套接字发送缓冲区有足够的空间容纳将要发送的数据;
  • 服务器接收连接请求:等待新的客户端连接请求的到来;
  • 客户端发送连接请求:等待服务器回送客户端发起的SYN所对应的ACK;

当一个网络IO发生时,会涉及到两个系统对象:(1)调用这个IO的进程;(2)系统内核;比如:当一个read操作发生时,会经历两个阶段:(1)等待数据准备;(2)将数据从内核拷贝到进程中
下面来介绍四种网络IO模型

1 四种网络IO模型

1.1 阻塞IO模型

  • 特点:在IO执行的两个阶段(等待数据和拷贝数据)都被阻塞
  • 存在的问题:会把整个线程阻塞,效率低下
  • 解决服务器处理效率时提到的几个概念:
    (1)线程池:旨在降低创建和销毁线程的频率,使其维持一定合理数量的线程,并让空闲的线程重新承担新的执行任务;
    (2)连接池:维持链接的缓存池,尽量重用已有的连接,降低创建和关闭连接的频率;

1.2 非阻塞IO模型

  • 特点:顾名思义就是在执行IO时,在等待数据阶段会直接返回,而不会阻塞,只有当数据准备好后,执行IO操作,在拷贝数据阶段会阻塞;
  • 设置非阻塞状态的接口:
    fcntl(fd, F_SETFL, O_NONBLOCK)
  • 存在的问题:需要循环执行IO操作,才能获取IO操作的结果

1.3 多路IO复用模型

  • 基本原理:有个函数(如select)会不断地轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程;调用select时,整个现场会被阻塞;
  • 注意:在多路复用IO模型中,对每个socket,都设置成非阻塞的;
  • 存在的问题:
    (1)select()接口并不是实现事件驱动的最好选择。因为当需要探测的句柄值较大时,select()接口本身需要消耗大量的时间去轮询各个句柄;
    (2)该模型将时间探测和事件响应夹杂在一起,一旦事件响应的执行体过于攀达,则对整个模型都是灾难性的。

1.4 异步IO模型

  • 特点:当进程发起IO操作之后,就直接返回,直到内核发送一个信号,告诉进程IO已完成,则在这整个过程中,进程完全没有被阻塞;
  • 接口:
    aio_read, aio_write

2 select

  • 接口:
    FD_ZERO(fd_set* fds); //将fds清零
    FD_SET(int fd, fd_set
    fds); //将fd加入fds
    FD_ISSET(int fd, fd_set* fds); //如果fd在fds中则为真
    FD_CLR(int fd, fd_set* fds); //将fd从fds中清除
    int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, struct timeval *timeout);

3 poll

  • 头文件和原型:
    #include <poll.h>
    int poll(struct pollfd *fds, unsigned int nfds, int timeout)
  • pollfd结构体定义:
    struct pollfd{
    int fd; //文件描述符
    short events; //等待的事件
    short revents; //实际发生的事件
    };

4 epoll

  • 头文件 #include <sys/epoll.h>
  • 操作过程中需要用到的三个接口:
    int epoll_create(int size);
    int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
    int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
  • epool_event结构体定义:
    struct epoll_event{
    __unit32_t events;
    epoll_data_t data;
    };

5 select、poll、epoll

select, poll, epoll本质都是同步IO
select与poll:
(1)poll不要求开发者计算最大文件描述符+1操作;
(2)poll在应付大数目的文件描述符时速度更快;
(3)select可以监控的文件描述符数目是固定的,相对来说较少;poll可以监控的文件数目远大于select
(4)所监控的fd_set在select返回之后会发生变化,所以在下一次进入select之前都需要重新初始化所需监控的fd_set,poll函数将监控的输入和输出时间分开,允许被监控的文件数组被复用而无需重新初始化;
(5)select函数的超时参数在返回时也是未定义的,考虑到可移植性,每次在超时之后再下一次进入到select之前都需要重新设置超时参数。

  • epoll的优点:
    1.支持一个进程打开大数目的sock描述符(FD)
    2.IO效率不随FD数目增加而线性下降
    3.使用mmap加速内核与用户空间的消息传递
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值