首页 > 编程知识 正文

企业服务器架构图,服务器技术架构发展三大趋势

时间:2023-05-05 16:56:26 阅读:141975 作者:1345

文章目录一、事件驱动二、事件驱动编程事件驱动和异步IO图查看事件驱动模型三、C/C实现事件驱动四、常用C/C事件驱动库

一.事件驱动

首先来看看百度百科的介绍吧。

事件驱动,简单来说就是你点击了什么按钮,也就是电脑执行了什么操作,也就是调用了什么函数。 当然,事件不限于用户的操作。 事件驱动的核心当然是事件。 从事件的角度看,事件驱动程序的基本结构由事件收集器、事件发射器和事件处理器组成。 事件收集器负责收集所有事件,包括来自用户的事件(如鼠标、键盘事件)、硬件事件(如时钟事件)和软件事件(如操作系统或APP应用程序本身) 事件发射器将收集器收集的事件分发到目标对象。 由于事件处理程序负责具体的事件响应工作,而且在大多数情况下,在实现阶段之前并不完全确定,因此必须使用虚函数机制(函数名称往往类似于HandleMsg )。 对于框架的使用者来说,他们能看到的是事件处理器。 这也是他们关心的内容。

视图(通常称为“窗口”)是事件驱动APP的另一个元素。 这是我们所说的事件发射器的目标。 视图可以接受和处理事件。 当我们把事件发送到具体视图时,实际上我们完成了根本性的变化。 是从传统的流线型程序结构向事件触发方式的转换。 这种APP应用具有相当大的灵活性,可以处理各种离散、随机的事件。

因为Windows本身基于“事件驱动”模式。 因此,在Windows操作系统上实现APP表示框架相当方便。 在事件驱动程序的基础单元中,事件收集器已经由Windows系统运行。 事件发送器也是Windows的一部分完成的。 之所以是部分而不是完整的,是因为Windows是用c语言而不是c实现的。 由于没有对象,Windows将事件发送到所谓的“窗口函数”(虽然它并不发送到特定的对象,但这应该称为面向对象方法实现的变体)。 感谢Windows做了这件事。 为确定事件目标而进行的工作的复杂性可能超出我们的想象。

您可以看到,对于事件驱动,最重要的是事件收集器、事件发射器和事件处理器。

二、事件驱动编程事件驱动和异步IO通常,服务器编写处理模型的程序时有以下几种模型:

)1)每次收到请求时,都会创建新的进程来处理该请求;

)2)每次收到请求时,都会创建一个新线程来处理该请求;

)3)每次收到请求时,都会加入事件列表,使主进程可以通过无阻断I/O方式处理请求

上面的几种方式,各有千秋,

在(1)的方法中,由于制作新工艺的开销大,所以服务器的性能会恶化,但实现比较简单。

)第二种方式,因为涉及线程的同步,所以有可能面临死锁等问题。

)第三种方式是,撰写APP二维码时,逻辑比前面两个复杂。

综合考虑各方面的因素,一般来说,第(3)方式被认为是很多网络服务器采用的方式

看图,事件驱动模型在UI编程中往往与鼠标点击相对应,首先如何获得鼠标点击呢?

方式一:创建一个线程,该线程一直循环检测是否有鼠标点击,那么这个方式有以下几个缺点:

在UI编程中,经常与鼠标点击相对应,那么首先如何获得鼠标点击呢?

方式一:创建一个线程,该线程一直循环检测是否有鼠标点击,那么这个方式有以下几个缺点:

虽然可能会浪费CPU资源,而且鼠标单击频率非常低,但是扫描线程总是在循环中被检测到,这会浪费很多CPU资源。 如果扫描和单击鼠标的界面被阻止了呢?

如果堵塞,则会出现以下问题。 除了鼠标单击外,还将扫描键盘是否被按下。 扫描鼠标时被卡住了,所以可能不会扫描键盘。

如果一个周期需要扫描的设备非常多,则会出现响应时间问题。

所以,这种方式非常不好。

方式二:就是事件驱动模型

目前,大多数UI编程都是事件驱动模型,许多UI平台都提供onClick )事件。 此事件表示鼠标按下事件。 事件驱动模型的大致思路如下。

有事件(消息)队列

按下鼠标时,将单击事件(消息)添加到此队列;

存在一个循环,用于继续从队列中检索事件,并为每个事件调用不同的函数,如onClick ()、onKeyDown ()

一般情况下,事件(消息)分别保持各自独立的处理函数指针。 这样,每个消息都有独立的处理函数;

事件驱动编程是编程的一种范式,在其中程序的执行流由外部事件确定。 其特征在于,它包含一个事件循环,在发生外部事件时使用回调机制触发相应的处理。 另外两种常见的编程范式是“单线程”同步和多线程编程。

通过示例比较和比较单线程、多线程和事件驱动的编程模型。 下图显示了随着时间的推移,程序将在这三种模式下执行的任务。 此程序需要完成三项任务,每个任务在等待I/O操作时都会阻止自身。 I/O操作所需的时间用灰色框表示。

在单线程同步模型中,任务按顺序执行。 如果任务因I/O而被阻止,则所有其他任务必须等待,直到完成。 这种明确的

执行顺序和串行化处理的行为是很容易推断得出的。如果任务之间并没有互相依赖的关系,但仍然需要互相等待的话这就使得程序不必要的降低了运行速度。

在多线程版本中,这3个任务分别在独立的线程中执行。这些线程由操作系统来管理,在多处理器系统上可以并行处理,或者在单处理器系统上交错执行。这使得当某个线程阻塞在某个资源的同时其他线程得以继续执行。与完成类似功能的同步程序相比,这种方式更有效率,但程序员必须写代码来保护共享资源,防止其被多个线程同时访问。多线程程序更加难以推断,因为这类程序不得不通过线程同步机制如锁、可重入函数、线程局部存储或者其他机制来处理线程安全问题,如果实现不当就会导致出现微妙且令人痛不欲生的bug。

在事件驱动版本的程序中,3个任务交错执行,但仍然在一个单独的线程控制中。当处理I/O或者其他昂贵的操作时,注册一个回调到事件循环中,然后当I/O操作完成时继续执行。回调描述了该如何处理某个事件。事件循环轮询所有的事件,当事件到来时将它们分配给等待处理事件的回调函数。这种方式让程序尽可能的得以执行而不需要用到额外的线程。事件驱动型程序比多线程程序更容易推断出行为,因为程序员不需要关心线程安全问题。

当我们面对如下的环境时,事件驱动模型通常是一个好的选择:

程序中有许多任务,而且…
任务之间高度独立(因此它们不需要互相通信,或者等待彼此)而且…
在等待事件到来时,某些任务会阻塞。
当应用程序需要在任务间共享可变的数据时,这也是一个不错的选择,因为这里不需要采用同步处理。

网络应用程序通常都有上述这些特点,这使得它们能够很好的契合事件驱动编程模型。

三、C/C++实现事件驱动

C/C++实现事件驱动,需要了解函数指针和回调等概念。

下面放一下之前写的相关的博客:

C语言注册机制原理及实现

C 语言跳转表的实现及在嵌入式设备中的应用

C语言回调函数详解(全网最全)

当然这些知识语言方面我们需要掌握的特性,要使用事件驱动编程,我们一般会使用事件驱动库。

四、常用的C/C++事件驱动库

因为一般事件驱动,都是针对的网络通信。

下面主要介绍一下libevent、libev、libuv。

Libevent、libev、libuv三个网络库,都是c语言实现的异步事件库Asynchronousevent library)。

异步事件库本质上是提供异步事件通知(Asynchronous Event Notification,AEN)的。异步事件通知机制就是根据发生的事件,调用相应的回调函数进行处理。

事件(Event):事件是异步事件通知机制的核心,比如fd事件、超时事件、信号事件、定时器事件。有时候也称事件为事件处理器(EventHandler),这个名称更形象,因为Handler本身表示了包含处理所需数据(或数据的地址)和处理的方法(回调函数),更像是面向对象思想中的称谓。

事件循环(EventLoop):等待并分发事件。事件循环用于管理事件。

对于应用程序来说,这些只是异步事件库提供的API,封装了异步事件库跟操作系统的交互,异步事件库会选择一种操作系统提供的机制来实现某一种事件,比如利用Unix/Linux平台的epoll机制实现网络IO事件,在同时存在多种机制可以利用时,异步事件库会采用最优机制。

技术对比:

1.libevent

C语言跨平台,应用最广泛,历史悠久的跨平台事件库。这是一个用纯C写的开源库,属于一个轻量级的网络中间件。其中用到的基本数据结构也是非常巧妙。展现反应堆模型的基本使用方法。不同的事件对应不容的处理方法。I/O 定时 信号。三种事件的处理单独分开,又通过事件驱动融合在一起。

优先级特性:激活的事件组织在优先级队列中,各类事件默认的优先级是相同的,可以通过设置事件的优先级使其优先被处理。

libevent在windows下支持iocp,但还不完善。

2.libev

设计更简练,性能更好,但因对Windows支持不够好。

优先级特性:激活的事件组织在优先级队列中,各类事件默认的优先级是相同的,可以通过设置事件的优先级使其优先被处理。

3.libuv

libuv是一个支持多平台的异步IO库。它主要是为了node.js而开发的。

优先级特性:没有优先级概念,按照固定的顺序访问各类事件。

因libuv为node.js定向开发,普遍应用性不好,且事件触发不可设定优先级,排除。

4.IOCP

IOCP是windows下IO事件处理的最高效的一种方式,结合OVERLAPPED IO可以实现真正的完全异步IO。不支持跨平台。

5.boost::asio

C++语言跨平台。用bind做回调也并不比虚函数好,看上去灵活了,代价却更高了。不光是运行时的内存和时间代价,编译时间也更长。基于ASIO开发应用,要求程序员熟悉函数对象,函数指针,熟悉boost库中的boost::bind,内存管理控制方面。

asio是一个高性能的网络开发库,Windows下使用IOCP,Linux下使用epoll。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。