关于静态网站开发相关新闻,做网上招聘哪个网站好,哪个网站做欧洲旅游攻略好,dede网站 设置404 错误页面文章目录Reactor模式Proactor模式同步I/O模型模拟Proactor模式两者的优缺点ReactorProactor同步I/O模型通常用于实现 Reactor 模式#xff0c;异步I/O模型通常用于实现 Proactor 模式。#xff08;不是绝对的#xff0c;同步I/O也可模拟出 Proactor 模式#xff09;
React…
文章目录Reactor模式Proactor模式同步I/O模型模拟Proactor模式两者的优缺点ReactorProactor同步I/O模型通常用于实现 Reactor 模式异步I/O模型通常用于实现 Proactor 模式。不是绝对的同步I/O也可模拟出 Proactor 模式
Reactor模式 原理 Reactor 模式要求主线程I/O处理单元只负责监听文件描述符上是否有事件就绪如果有则将该就绪事件通知给工作线程逻辑单元。除此之外主线程不会进行其他实质性的工作读写数据、接收新连接、业务逻辑处理全部在工作线程中完成。 工作流程 这里以 epoll_wait 为例使用同步I/O模型实现的 Reactor 模式的工作流程如下
主线程往 epoll 内核事件表中注册 socket 上的读就绪事件。主线程调用 epoll_wait 开始对 socket 的读事件进行监控。如果 socket 读就绪epoll_wait 会通知主线程主线程则将 socket 可读事件即 socket 连接本身 放入请求队列中。请求队列上某个休眠的工作线程被唤醒此时会从 socket 中读取数据并且处理用户请求然后往 epoll 内核事件表中注册该 socket 的写就绪事件。主线程继续调用 epoll_wait 对 socket 的写事件进行监控。当 socket 写就绪时epoll_wait 会通知主线程主线程则将 socket 可写事件即 socket 连接本身 放入请求队列中。请求队列上某个休眠的工作线程被唤醒将服务器处理客户请求的结果写入到 socket 中 工作线程从请求队列中取出事件后根据事件类型来决定如何处理事件所以不会区分 读工作线程 和 写工作线程。 Proactor模式 原理 Proactor模式则是将所有的I/O操作全部交给主线程和内核处理工作线程仅仅负责业务逻辑。 工作流程 这里以 aio 为例使用异步I/O模型实现的 Reactor 模式的工作流程如下
主线程调用 aio_read 向内核注册 socket 上的读完成事件并且告诉内核用户读缓冲区的位置以及读操作完成时如何通知应用程序这里以信号为例。I/O事件交给内核进行异步处理此时主线程继续处理其他逻辑区别于 Reactor 中主线程需要持续监控就绪事件。当 socket 上的数据已被读入用户缓冲区后内核向应用程序发送一个信号通知其数据已可用。通过应用程序预先定义好的信号处理函数来选择一个工作线程以处理客户请求。工作线程处理完客户请求之后会调用 aio_write 向内核注册 socket 上的写就绪事件并且告诉内核用户写缓冲区的位置以及写操作完成时如何通知应用程序仍选择使用信号。主线程继续处理其他逻辑同2。当用户缓冲区的数据被写入 socket 后内核向应用程序发送一个信号通知其数据发送完成。通过应用程序 注册预先定义好 的信号处理 事件函数 来选择一个工作线程来进行善后处理例如是否关闭 socket。 由于读/写事件是通过 aio_read/aio_write 向内核中进行 注册 的并由内核通过 信号 向应用程序 报告 的。因此不同于 Reactor 模式Proactor 的 epoll_wait 仅仅用来监听 socket 上是否有新的连接请求到来而不用于 注册 or 报告 读/写事件。 同步I/O模型模拟Proactor模式 原理 主线程执行数据读写操作完成后向工作线程通知事件的完成。从工作线程的角度来看他们就直接获得了数据读写的结果接下来的工作就只需要对读写结果进行业务逻辑处理。 工作流程 这里以 epoll_wait 为例使用同步I/O模型实现的 Proactor 模式的工作流程
主线程往 epoll 内核事件表中注册 socket 上的读就绪事件。同步I/O注册就绪事件、异步I/O注册完成事件主线程调用 epoll_wait 等待 socket 上有数据可读。当 socket 上有数据可读epoll_wait 通知主线程主线程从 socket 中循环读取数据直到没有数据可读。然后将读到的数据封装成一个请求对象插入请求队列中。请求队列上某个休眠的工作线程被唤醒此时它会获取请求对象并且处理客户请求然后往 epoll 内核事件表中注册 socket 的写就绪事件。主线程调用 epoll_wait 等待 socket 可写。如果 socket 写就绪epoll_wait 通知主线程主线程往 socket 中写入服务器处理客户请求的结果。 两者的优缺点
Reactor
Reactor 实现了一个被动的事件分离和分发模型
主线程只负责监听读写事件是否就绪就绪后放入请求队列并唤醒请求队列上某个工作线程由工作线程读写数据并处理客户请求。
优点
实现相对简单对于耗时短的处理场景处理高效。操作系统可以在多个事件源上等待并且避免了多线程编程相关的性能开销和编程复杂性。事件的串行化对应用是透明的可以顺序的同步执行而不需要加锁。将与应用无关的多路分解、分配机制和与应用相关的回调函数分离开来。
缺点
处理耗时长的操作会造成事件分发的阻塞影响到后续事件的处理。
适用场景
同时接收多个服务请求并且依次同步处理它们的事件驱动程序。 Proactor
Proactor 实现了一个主动的事件分离和分发模型
主线程监听事件是否就绪内核执行I/O操作读写数据上一步完成后根据预先注册好的信号函数选择一个工作线程处理客户请求。
优点
性能更高能够适应耗时长的并发场景各个任务间互不影响这种设计允许多个任务并发的执行从而提高吞吐量。
缺点
实现逻辑复杂依赖操作系统对异步的支持目前实现了纯异步操作的操作系统少。 实现优秀的如 windows IOCP但由于 windows 系统用于服务器的局限性目前应用范围较小。而 Unix/Linux 系统对纯异步的支持有限应用事件驱动的主流方案还是通过 select/epoll 来实现。
适用场景
异步接收、同时处理多个服务请求的事件驱动程序。