1:IO事件驱动模型简介

通常,我们写服务器处理模型的程序时,有以下几种模型:
(1)每收到一个请求,创建一个新的进程,来处理该请求;
(2)每收到一个请求,创建一个新的线程,来处理该请求;
(3)每收到一个请求,放入一个事件列表,让主进程通过非阻塞I/O方式来处理请求
上面的几种方式,各有千秋,
第(1)中方法,由于创建新的进程的开销比较大,所以,会导致服务器性能比较差,但实现比较简单。
第(2)种方式,由于要涉及到线程的同步,有可能会面临死锁等问题。
第(3)种方式,在写应用程序代码时,逻辑比前面两种都复杂。
综合考虑各方面因素,一般普遍认为第(3)种方式是大多数网络服务器采用的方式

看图说话讲事件驱动模型

在UI编程中,常常要对鼠标点击进行相应,首先如何获得鼠标点击呢?
方式一:创建一个线程,该线程一直循环检测是否有鼠标点击,那么这个方式有以下几个缺点
1. CPU资源浪费,可能鼠标点击的频率非常小,但是扫描线程还是会一直循环检测,这会造成很多的CPU资源浪费;如果扫描鼠标点击的接口是阻塞的呢?
2. 如果是堵塞的,又会出现下面这样的问题,如果我们不但要扫描鼠标点击,还要扫描键盘是否按下,由于扫描鼠标时被堵塞了,那么可能永远不会去扫描键盘;
3. 如果一个循环需要扫描的设备非常多,这又会引来响应时间的问题;
所以,该方式是非常不好的。

方式二:就是事件驱动模型
目前大部分的UI编程都是事件驱动模型,如很多UI平台都会提供onClick()事件,这个事件就代表鼠标按下事件。事件驱动模型大体思路如下:
1. 有一个事件(消息)队列;
2. 鼠标按下时,往这个队列中增加一个点击事件(消息);
3. 有个循环,不断从队列取出事件,根据不同的事件,调用不同的函数,如onClick()、onKeyDown()等;
4. 事件(消息)一般都各自保存各自的处理函数指针,这样,每个消息都有独立的处理函数;

事件驱动编程是一种编程范式,这里程序的执行流由外部事件来决定。它的特点是包含一个事件循环,当外部事件发生时使用回调机制来触发相应的处理。另外两种常见的编程范式是(单线程)同步以及多线程编程。

让我们用例子来比较和对比一下单线程、多线程以及事件驱动编程模型。下图展示了随着时间的推移,这三种模式下程序所做的工作。这个程序有3个任务需要完成,每个任务都在等待I/O操作时阻塞自身。阻塞在I/O操作上所花费的时间已经用灰色框标示出来了。

在单线程同步模型中,任务按照顺序执行。如果某个任务因为I/O而阻塞,其他所有的任务都必须等待,直到它完成之后它们才能依次执行。这种明确的执行顺序和串行化处理的行为是很容易推断得出的。如果任务之间并没有互相依赖的关系,但仍然需要互相等待的话这就使得程序不必要的降低了运行速度。

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

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

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

  1. 程序中有许多任务,而且…
  2. 任务之间高度独立(因此它们不需要互相通信,或者等待彼此)而且…
  3. 在等待事件到来时,某些任务会阻塞。

当应用程序需要在任务间共享可变的数据时,这也是一个不错的选择,因为这里不需要采用同步处理。

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

IO事件驱动模型的更多相关文章

  1. python网络编程--事件驱动模型

    论事件驱动与异步IO 事件驱动模型:根据事件的触发去干什么事,就是根据一个事件做反应 原文:http://www.cnblogs.com/alex3714/articles/5248247.html常 ...

  2. 事件驱动模型和异步IO多路复用

    事件驱动模型 协程:遇到IO操作就切换. 但什么时候切回去呢?怎么确定IO操作完了? 很多程序员可能会考虑使用“线程池”或“连接池”.“线程池”旨在减少创建和销毁线程的频率,其维持一定合理数量的线程, ...

  3. Day14 - Python基础14 事件驱动模型、IO模型

    本节内容: 1:事件驱动模型 2:IO模型前戏准备 3:4种IO模型 1:事件驱动模型 传统的编程是如下线性模式的: 开始--->代码块A--->代码块B--->代码块C---> ...

  4. (六)观察者模式详解(包含观察者模式JDK的漏洞以及事件驱动模型)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 本章我们讨论一个除前面的单例 ...

  5. Python自动化之select、greenlet和gevent和事件驱动模型初探

    进程.线程和协程的区别 进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调度. 线程拥有自己独立的栈和共享的堆,共享堆,不共享栈,线程亦由操作系统调度(标准线程是的). 协程和线程一样 ...

  6. Nginx 之三:nginx服务器模块、web请求处理机制及事件驱动模型、进程功能和进程间通信

    一:Nginx的模块化结构设计: 1.核心模块:指的是nginx服务器运行当中必不可少的模块,这些模块提供了最基本最核心的服务,比如权限控制.进程管理.错误日志.事件驱动.正则表达式解析等,nginx ...

  7. 设计模式之 观察者模式详解(包含观察者模式JDK的漏洞以及事件驱动模型)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 本章我们讨论一个除前面的单例 ...

  8. Python并发编程-事件驱动模型

     一.事件驱动模型介绍                                                                                         ...

  9. IO阻塞模型 非阻塞模型

       IO阻塞模型(blocking IO) 在linux中,默认情况下所有的socket都是blocking,一个典型的读操作流程大概是这样:  所以,blocking IO的特点就是在IO执行的两 ...

随机推荐

  1. Spark架构

    Spark架构    为了更好地理解调度,我们先来鸟瞰一下集群模式下的Spark程序运行架构图. 1. Driver Program        用户编写的Spark程序称为Driver Progr ...

  2. Cordova安装、设置代理和引入插件

    cardova代理 $ npm config --global set registry http://registry.cnpmjs.org cardova添加插件 格式:cordova plugi ...

  3. Apache Commons Digester 二(规则模块绑定-RulesModule、异步解析-asyncParse、xml变量Substitutor、带参构造方法)

    前言 上一篇对Digester做了基本介绍,也已经了解了Digester的基本使用方法,接下来将继续学习其相关特性,本篇主要涉及以下几个内容: 规则模块绑定,通过定义一个RulesModule接口实现 ...

  4. 从零开始学 Web 之 Ajax(一)服务器相关概念

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  5. ProxySQL Cluster 高可用集群环境部署记录

    ProxySQL在早期版本若需要做高可用,需要搭建两个实例,进行冗余.但两个ProxySQL实例之间的数据并不能共通,在主实例上配置后,仍需要在备用节点上进行配置,对管理来说非常不方便.但是Proxy ...

  6. 深度学习之PyTorch实战(3)——实战手写数字识别

    上一节,我们已经学会了基于PyTorch深度学习框架高效,快捷的搭建一个神经网络,并对模型进行训练和对参数进行优化的方法,接下来让我们牛刀小试,基于PyTorch框架使用神经网络来解决一个关于手写数字 ...

  7. #9 Python列表和元组

    前言 Python中有6种序列:列表.元组.字符串.Unicode字符串.buffer对象和xrange对象.序列通用操作包括:索引.切片.长度.加.乘.最大值.最小值,遍历和检查成员.虽然Pytho ...

  8. 突发奇想想学习做一个HTML5小游戏

    前言: 最近一期文化馆轮到我分享了,分享了两个,一个是关于童年教科书的回忆,一个是关于免费电子书的.最后我觉得应该会不敌web,只能说是自己在这中间回忆了一下那个只是会学习的年代,那个充满梦想的年代. ...

  9. MySQL储存过程

    储存过程 本文章原创,转载需注明出处. 前提: 在大型数据库中 来源: 为了完成特定功能的SQL语句集 定义: 储存在数据库中, 用户通过指定储存过程的名字并给出参数(带有参数的)来执行它 声明: 储 ...

  10. Django之stark组件

    现在让我说啥是stark组件,我也说不清楚.反正从今天讲的知识来看,今天完成的就是自己写一个模块,这个模块包含了admin后台管理工具的一些比较好用的功能,我们把它提炼出来,也就是相当于自己写一个ad ...