| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 系统运维 -> Linux高性能之服务框架(11) -> 正文阅读 |
|
[系统运维]Linux高性能之服务框架(11) |
前言I/O处理单元:本博客将介绍IO处理单元的四种IO模型和两种高效事件处理模式。逻辑单元。本章将介绍逻辑单元的两种高效并发模式,以及高效的逻辑处理方式——有限状态机。 服务器模型C/S模型最重要:C/S模型非常适应于资源相对集中的场合 TCP/IP协议在设计和实现上并没有客户端和服务器的概念,在通信过程中所有机器都是对等的。但由于资源(视频、新闻、软件等)都被数据提供者所垄断,所以几乎所有的网络应用程序都很自然地采用了下图所示的C/S(客户端/服务器)模型:所有客户端都通过访问服务器来获取所需的资源。 P2PP2P(Peer to Peer,点对点)模型比CIS模型更符合网络通信的实际情况。它摒弃了以服务器为中心的格局,让网络上所有主机重新回归对等的地位。 服务器编程框架
一个逻辑单元通常是一个进程或线程。它分析并处理客户数据,然后将结果传递给IO处理单元或者直接发送给客户端(具体使用哪种方式取决于事件处理模式)。对服务器机群而言,一个逻辑单元本身就是一台逻辑服务器。服务器通常拥有多个逻辑单元,以实现对多个客户任务的并行外理。 网络储存单元以是数据厍、缓仔和文件,甚至是一台独立的服务器。但它不是必须的,比如ssh、telnet等登录服务就不需要这个单元。 请求队列是各单元之间的通信方式的抽象。IO处理单元接收到客户请求时,需要以某种方式通知一个逻辑单元来处理该请求。同样,多个逻辑单元同时访问一个存储单元时,也需要采用某种机制来协调处理竞态条件**。请**求队列通常被实现为池的一部分,我们将在后面讨论池的概念。对于服务器机群而言,请求队列是各台服务器之间预先建立的、静态的、永久的TCP连接。这种TCP连接能提高服务器之间交换数据的效率,因为它避免了动态建立TCP连接导致的额外的系统开销。 I/O模型这篇博客讲到,socket在创建的时候默认是阻塞的。我们可以给socket系统调用的第2个参数传递SOCK_NONBLOCK标志,或者通过fcntl系统调用的F_SETFL命令,将其设置为非阻塞的。阻塞和非阻塞的概念能应用于所有文件描述符,而不仅仅是socket。我们称阻塞的文件描述符为阻塞I/O,称非阻塞的文件描述符为非阻塞IO. 针对阻塞IO执行的系统调用可能因为无法立即完成而被操作系统挂起,直到等待的事件发生为止。比如,客户端通过conncct向服务器发起连接时,connect将首先发送同步报文段给服务器,然后等待服务器返回确认报文段。如果服务器的确认报文段没有立即到达客户端,则connect调用将被挂起,直到客户端收到确认报文段并唤醒conncct调用。socket 的基础API中,可能被阻塞的系统调用包括accept、send、recv和 connect。 针对非阻塞IO执行的系统调用则总是立即返回,而不管事件是否已经发生。如果事件没有立即发生,这些系统调用就返回-1,和出错的情况一样。此时我们必须根据errno来区分这两种情况。 结论:很显然,我们只有在事件已经发生的情况下操作非阻塞IO(读、写等),才能提高程序的效率。因此,非阻塞IO通常要和其他IO通知机制一起使用,比如IO复用和SIGIO信号。 I/O复用: SIGIO信号也可以用来报告IO事件。这个博客的最后一段提到,我们可以为一个目标文件描述符指定宿主进程,那么被指定的宿主进程将捕获到SIGIO信号。这样,当目标文件描述符上有事件发生时,SIGIO信号的信号处理函数将被触发,我们也就可以在该信号处理函数中对目标文件描述符执行非阻塞IO操作了。 从理论上说,阻塞IO、IO复用和信号驱动I/O都是同步IO模型。因为在这三种IO模型中,IO的读写操作,都是在IO事件发生之后,由应用程序来完成的。而 POSIX规范所定义的异步IO模型则不同**。对异步IO而言,用户可以直接对IO执行读写操作,这些操作告诉内核用户读写缓冲区的位置,以及I/O操作完成之后内核通知应用程序的方式**。异步IO的读写操作总是立即返回,而不论IO是否是阻塞的,因为真正的读写操作已经由内核接管。也就是说,同步IO模型要求用户代码自行执行IO操作(将数据从内核缓冲区读人用户缓冲区,或将数据从用户缓冲区写人内核缓冲区),而异步I/O机制则由内核来执行1/О操作(数据在内核缓冲区和用户缓冲区之间的移动是由内核在“后台”完成的)。你可以这样认为,同步IO向应用程序通知的是IO就绪事件,而异步IO向应用程序通知的是IO完成事件。Linux环境下,aio.h头文件中定义的函数提供了对异步IO的支持。
两种高效的事件处理方式前言服务器程序通常需要处理三类事件**:IO事件、信号及定时事件**。我们将在后续博客依次讨论这三种类型的事件,这一节先从整体上介绍一下两种高效的事件处理模式: Reactor和Proactor. ReactorReactor是这样一种模式,它要求主线程(IO处理单元,下同)只负责监听文件描述上是否有事件发生,有的话就立即将该事件通知工作线程(逻辑单元,下同)。除此之外,主线程不做任何其他实质性的工作。读写数据,接受新的连接,以及处理客户请求均在工作线程中完成。 使用同步IO模型(以epoll_wait为例)实现的Reactor模式的工作流程是: Proactor(siganl)使用异步IO模型(以aio_read和aio_write为例)实现的Proactor模式的工作流程是:
模拟Proactor上文提到了使用同步IO方式模拟出Proactor模式的一种方法。其原理是﹔主线程执行数据读写操作,读写完成之后,主线程向工作线程通知这一“完成事件”。那么从工作线程的角度来看,它们就直接获得了数据读写的结果,接下来要做的只是对读写的结果讲行逻辑处理 1)主线程往epoll 内核事件表中注册socket 上的读就绪事件。 两种高效的并发模式并发编程的目的是让程序“同时”执行多个任务。 半同步/半异步模式在并发模式中,“同步”指的是程序完全按照代码序列的顺序执行:“异步指的是程序的执行需要由系统事件来驱动。常见的系统事件包括中断、信号等。
半同步/半异步模式中,同步线程用于处理客户逻辑﹔ 升级相对高效半同步/半异步的模式
领导者模式/追随者模式领导者/追随者模式是多个工作线程轮流获得事件源集合,轮流监听、分发并处理事件的一种模式。在任意时间点,程序都仅有一个领导者线程,它负责监听IO事件。而其他线程则都是追随者,它们休眠在线程池中等待成为新的领导者。当前的领导者如果检测到IO事件,首先要从线程池中推选出新的领导者线程,然后处理IO事件。此时,新的领导者等待新的IO事件,而原来的领导者则处理IO事件,二者实现了并发。 领导者/追随者模式包含如下几个组件:句柄集(HandleSet)、线程集(ThreadSet)、事件处理器(EventHandler)和具体的事件处理器(ConcreteEventHandler)。它们的关系如下: 2.线程集 **Leader:**线程当前处于领导者身份,负责等待句柄集上的IO事件。 3.事件处理器和具体的事件处理器 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 | -2024/12/28 19:40:07- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |
数据统计 |