典型IO模型,多路转接/多路复用模型

阻塞 IO: 在内核将数据准备好之前 , 系统调用会一直等待 . 所有的套接字 , 默认都是阻塞方式

非阻塞IO: 如果内核还未将数据准备好, 系统调用仍然会直接返回, 并且返回EWOULDBLOCK错误码,非阻塞IO往往需要程序员循环的方式反复尝试读写文件描述符, 这个过程称为轮询. 这对CPU来说是较大的浪费, 一 般只有特定场景下才使用。

 信号驱动IO: 内核将数据准备好的时候, 使用SIGIO信号通知应用程序进行IO操作

IO 多路转接 : 虽然从流程图上看起来和阻塞 IO 类似 . 实际上最核心在于 IO 多路转接能够同时等待多个文件 描述符的就绪状态
异步 IO: 由内核在数据拷贝完成时 , 通知应用程序 ( 而信号驱动是告诉应用程序何时可以开始拷贝数据 ).

阻塞与非阻塞:
阻塞:发起一个操作,若当前操作条件不满足则一直等待

非阻塞:发起一个操作,若当前操作条件不满足则报错返回

阻塞与非阻塞关联:通常都是操作接口特性

阻塞与非阻寨区别: 发起一个接口调用后,接口是否会立即返回同步与异步
同步:功能由进程自身完成,并且通常是串行化的。

异步: 功能并不由进程自身完成,而是由系统完成,完成不一定是串行的

同步与异步的关联: 通常用于讨论一个任务的完成流程

同步与异步的区别: 功能是否由当前执行流自身完成。

异步阻塞:发起操作后,功能由系统完成,进程执行流自身等待系统完成

异步非阻塞:发起操作后,功能由系统完成,操作会直接返回,并不会等待

多路转接模型:常用于高并发服务器中技术的使用

作用:针对大量描述符进行IO就绪事件

监控优点:
1.让进程能够仅针对就绪的描述符进行IO操作,提高了任务处理效率

2.避免进程因为对于未就绪描述符进行操作,而导致阻塞这种情况

具体技术实现: select, poll, epoll

mongoose这个库的搭建服务器实现思想: 单进程+多路转接模型

select模型
lO事件: 可读事件,可写事件, 异常事件

流程思想
1.定义指定IO事件的描述符集合 

2.将需要对指定事件进行监控的描述符添加到指定集合中
3.将事件的描述符集合,拷贝到内核中,进行事件监控

1).对集合中的所有描述进行一次遍历(判断有没有就绪,以及挂起),若没有就绪则将描述符挂到内核的IO事件队列

2).若监控过程中,有某个描述就绪了所要监控的事件,则会唤醒进程的阻塞

3).被唤醒后,select会再次将描述符集合遍历一遍,将集合中没有就绪的描述符移除

4.select监控返回后,只需要判断哪个描述符还在集合中,哪个描述符就就绪了哪个事件

5.进程就可以根据就绪的不同事件对描述符进行不同的IO操作。

接口:

3.开始监控

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

 select接口一旦返回,就意味着这三个集合中,就只保留了就绪了指定事件的描述符

4.判断哪个描述符还在集合中,哪个描述符就就绪了哪个事件

int FD ISSET(int fd,fd set *set); 判断fd描述符,是否在set集合中

将select应用在tcp服务器搭建上。

搭建一个tcp服务器,会涉及到服务器端为每一个客户端连接都会创建一个新的套接字,进行通信,需要需要对大量的描述符进行IO操作

但是因为之前,有可能会因为对没有就绪的描述符进行操作而导致程序流程阻塞

因此当时的解决方案:多执行流解决方案 (为每一个客户端的通信都创建执行流)

而最好的解决方案:多路转接模型+线程池

如何在单执行流中对大量描述符进行轮询处理

 poll:操作流程

1.定义一个事件结构体数组

#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
// pollfd结构
struct pollfd {
   int   fd;         /* file descriptor */监控的文件描述
   short events;     /* requested events */想要监控的事件,POLLIN可读,POLLOUT可写
   short revents;   /* returned events */监控返回后,储存实际就绪的事件
};

2.如果描述符需要监控什么事件,就在数组进行设置

 epoll

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);

 优点:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值