Linux高性能网络IO和Reactor模型的示例分析

发布时间:2021-06-30 14:03:38 作者:小新
来源:亿速云 阅读:225

小编给大家分享一下Linux高性能网络IO和Reactor模型的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

目录

一、基本概念介绍

在零拷贝机制篇章已介绍过 用户空间和内核空间和缓冲区,这里就省略了

二、网络IO的读写过程

三、Linux五种网络IO模型

3.1、阻塞式I/O (blocking IO)

ssize_t recvfrom(int sockfd,void *buf,size_t len,unsigned int flags, struct sockaddr *from,socket_t *fromlen);

Linux高性能网络IO和Reactor模型的示例分析

3.2、非阻塞式I/O (nonblocking IO)

Linux高性能网络IO和Reactor模型的示例分析

3.3、多路复用I/O (IO multiplexing)

Linux高性能网络IO和Reactor模型的示例分析

3.4、信号驱动式I/O (SIGIO)

Linux高性能网络IO和Reactor模型的示例分析

3.5、异步IO (POSIX的aio_系列函数)

Linux高性能网络IO和Reactor模型的示例分析

四、多路复用IO深入理解一波

4.1、select

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

1)使用copy_from_user从用户空间拷贝fd_set到内核空间

2)注册回调函数__pollwait

3)遍历所有fd,调用其对应的poll方法(对于socket,这个poll方法是sock_poll,sock_poll根据情况会调用到tcp_poll,udp_poll或者datagram_poll)

4)以tcp_poll为例,其核心实现就是__pollwait,也就是上面注册的回调函数

5)__pollwait的主要工作就是把current(当前进程)挂到设备的等待队列中,不同的设备有不同的等待队列,对于tcp_poll来说,其等待队列是sk->sk_sleep(注意把进程挂到等待队列中并不代表进程已经睡眠了)。在设备收到一条消息(网络设备)或填写完文件数据(磁盘设备)后,会唤醒设备等待队列上睡眠的进程,这时current便被唤醒了

6)poll方法返回时会返回一个描述读写操作是否就绪的mask掩码,根据这个mask掩码给fd_set赋值

7)如果遍历完所有的fd,还没有返回一个可读写的mask掩码,则会调用schedule_timeout是调用select的进程(也就是current)进入睡眠

8) 当设备驱动发生自身资源可读写后,会唤醒其等待队列上睡眠的进程。如果超过一定的超时时间(timeout指定),还是没人唤醒,则调用select的进程会重新被唤醒获得CPU,进而重新遍历fd,判断有没有就绪的fd

9)把fd_set从内核空间拷贝到用户空间

select的缺点:

4.2、epoll

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

epoll的两种触发模式:

epoll有EPOLLLT和EPOLLET两种触发模式,LT是默认的模式,ET是“高速”模式(只支持no-block socket)

4.3、epoll相比select的优点

解决select三个缺点:

epoll的高性能:

4.4、关于epoll的IO模型是同步异步的疑问

概念定义:

异步IO的概念是要求无阻塞I/O调用。前面有介绍到I/O操作分两阶段:R1等待数据准备好。R2从内核到进程拷贝数据。虽然epoll在2.6内核之后采用mmap机制,使得其在R2阶段不需要复制,但是它在R1还是阻塞的。因此归类到同步IO

五、Reactor模型

Reactor的中心思想是将所有要处理的I/O事件注册到一个中心I/O多路复用器上,同时主线程/进程阻塞在多路复用器上;一旦有I/O事件到来或是准备就绪,多路复用器返回,并将事先注册的相应I/O事件分发到对应的处理器中

5.1、相关概念介绍

5.2、Reactor的一般流程

1)应用程序在事件分离器注册读写就绪事件和读写就绪事件处理器

2)事件分离器等待读写就绪事件发生

3)读写就绪事件发生,激活事件分离器,分离器调用读写就绪事件处理器

4)事件处理器先从内核把数据读取到用户空间,然后再处理数据

Linux高性能网络IO和Reactor模型的示例分析

5.3、单线程 + Reactor

Linux高性能网络IO和Reactor模型的示例分析

5.4、多线程 + Reactor

Linux高性能网络IO和Reactor模型的示例分析

5.5、多线程 + 多个Reactor

Linux高性能网络IO和Reactor模型的示例分析

六、Proactor模型的一般流程

1)应用程序在事件分离器注册读完成事件和读完成事件处理器,并向系统发出异步读请求

2)事件分离器等待读事件的完成

3)在分离器等待过程中,系统利用并行的内核线程执行实际的读操作,并将数据复制进程缓冲区,最后通知事件分离器读完成到来

4)事件分离器监听到读完成事件,激活读完成事件的处理器

5)读完成事件处理器直接处理用户进程缓冲区中的数据

Linux高性能网络IO和Reactor模型的示例分析

6.1、Proactor和Reactor的区别

以上是“Linux高性能网络IO和Reactor模型的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

推荐阅读:
  1. Java网络IO模型及分类
  2. Java中网络IO编程的示例分析

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

linux io reactor

上一篇:python中如何使用not运算符

下一篇:Qt4和Qt5的信号和槽的使用区别有哪些

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》