精华内容
下载资源
问答
  • 2019-04-11 22:39:21

    一、两种分类:
    1、观察者模式:java自带观察者模式类,可直接实现,一个事件源发生事件 触发对 应观察者
    2、订阅发布模式:订阅端 事件通道 发布端 解耦度高,优选

    二、三种实现
    1、spring框架实现 自带了事件监听的相关类,是对java jdk的监听事件的优化
    2、zookeper 实现配置文件的热部署,配置在节点中存贮 ,在java中添加zookeper相关watcher代码,利用zookerper带有的watcher来监听节点的变化,从而在java项目中对配置进行不停机更新
    3、消息中间件,主要用于微服务之间的通信和解耦,适用于同一项目下有较多服务的情况

    更多相关内容
  • 文章目录一、事件驱动二、事件驱动编程事件驱动和异步IO看图说话讲事件驱动模型三、C/C++实现事件驱动四、常用的C/C++事件驱动库 一、事件驱动 首先我们来看看百度百科的介绍。 所谓事件驱动,简单地说就是你点什么...

    一、事件驱动

    首先我们来看看百度百科的介绍。

    所谓事件驱动,简单地说就是你点什么按钮(即产生什么事件),电脑执行什么操作(即调用什么函数).当然事件不仅限于用户的操作. 事件驱动的核心自然是事件。从事件角度说,事件驱动程序的基本结构是由一个事件收集器、一个事件发送器和一个事件处理器组成。事件收集器专门负责收集所有事件,包括来自用户的(如鼠标、键盘事件等)、来自硬件的(如时钟事件等)和来自软件的(如操作系统、应用程序本身等)。事件发送器负责将收集器收集到的事件分发到目标对象中。事件处理器做具体的事件响应工作,它往往要到实现阶段才完全确定,因而需要运用虚函数机制(函数名往往取为类似于HandleMsg的一个名字)。对于框架的使用者来说,他们能够看到的是事件处理器。这也是他们所关心的内容。

    视图(即我们通常所说的“窗口”)是“事件驱动”应用程序的另一个要元。它是我们所说的事件发送器的目标对象。视图接受事件并能够对其进行处理。当我们将事件发送到具体的视图时,实际上我们完成了一个根本性的变化:从传统的流线型程序结构到事件触发方式的转变。这样应用程序具备相当的柔性,可以应付种种离散的、随机的事件。

    由于Windows本身是基于“事件驱动”模型的。因而在Windows操作系统下实现应用程序框架有相当的便利。在事件驱动程序的基本单元中,事件收集器已经由Windows系统完成;事件发送器也已经由Windows完成了部分内容。之所以是部分而非完全是因为Windows是用C语言实现的,而不是C++。由于没有对象,Windows将事件发送到所谓的“窗口函数”中(尽管不是发送到具体的对象,但应该说这是面向对象方式实现的一个变体)。要感谢Windows做了这件事。确定事件的目标所要做的工作的复杂可能要超出我们的想象。

    可以看到对于事件驱动来说,最重要的是一个事件收集器、一个事件发送器和一个事件处理器。

    二、事件驱动编程

    事件驱动和异步IO

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

    看图说话讲事件驱动模型

    在UI编程中,常常要对鼠标点击进行相应,首先如何获得鼠标点击呢?
    方式一:创建一个线程,该线程一直循环检测是否有鼠标点击,那么这个方式有以下几个缺点:

    在UI编程中,常常要对鼠标点击进行相应,首先如何获得鼠标点击呢?
    方式一:创建一个线程,该线程一直循环检测是否有鼠标点击,那么这个方式有以下几个缺点:

    1. CPU资源浪费,可能鼠标点击的频率非常小,但是扫描线程还是会一直循环检测,这会造成很多的CPU资源浪费;如果扫描鼠标点击的接口是阻塞的呢?

    2. 如果是堵塞的,又会出现下面这样的问题,如果我们不但要扫描鼠标点击,还要扫描键盘是否按下,由于扫描鼠标时被堵塞了,那么可能永远不会去扫描键盘;

    3. 如果一个循环需要扫描的设备非常多,这又会引来响应时间的问题;
      所以,该方式是非常不好的。

    方式二:就是事件驱动模型
    目前大部分的UI编程都是事件驱动模型,如很多UI平台都会提供onClick()事件,这个事件就代表鼠标按下事件。事件驱动模型大体思路如下:

    1. 有一个事件(消息)队列;

    2. 鼠标按下时,往这个队列中增加一个点击事件(消息);

    3. 有个循环,不断从队列取出事件,根据不同的事件,调用不同的函数,如onClick()、onKeyDown()等;

    4. 事件(消息)一般都各自保存各自的处理函数指针,这样,每个消息都有独立的处理函数;

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

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

    img

    在单线程同步模型中,任务按照顺序执行。如果某个任务因为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。

    展开全文
  • Windows驱动编程基础教程,Windows驱动编程基础教程,Windows驱动编程基础教程,Windows驱动编程基础教程,Windows驱动编程基础教程
  • 事件驱动 基本概念 窗口/组件 事件 消息(队列) 事件响应(服务处理程序) 调度算法 进程/线程 非阻塞I/O 程序的执行可以看成对CPU,内存,IO资源一次占用 现代操作系统支持...

    事件驱动

    基本概念

    • 窗口/组件

    • 事件

    • 消息(队列)

    • 事件响应(服务处理程序)

    • 调度算法

    • 进程/线程

    • 非阻塞I/O

    • 程序的执行可以看成对CPU,内存,IO资源一次占用

    • 现代操作系统支持多任务,可以分时复用上述资源.

    1. 为什么采用事件驱动模型?

    事件驱动模型也就是我们常说的观察者,或者发布-订阅模型;理解它的几个关键点:

    • 首先是一种对象间的一对多的关系;最简单的如交通信号灯,信号灯是目标(一方),行人注视着信号灯(多方);

    • 当目标发送改变(发布),观察者(订阅者)就可以接收到改变;

    • 观察者如何处理(如行人如何走,是快走/慢走/不走,目标不会管的),目标无需干涉;所以就松散耦合了它们之间的关系。

    2. 代码执行流程

    在传统的或“过程化”的应用程序中,应用程序自身控制了执行哪一部分代码和按何种顺序执行代码。从第一行代码执行程序并按应用程序中预定的路径执行,必要时调用过程。
    在事件驱动的应用程序中,代码不是按照预定的路径执行-而是在响应不同的事件时执行不同的代码片段。事件可以由用户操作触发、也可以由来自操作系统或其它应用程序调度算法的消息触发、甚至由应用程序本身的消息触发。这些事件的顺序决定了代码执行的顺序,因此应用程序每次运行时所经过的代码的路径都是不同的。

    3. 事件驱动模型

    在UI编程中,常常要对鼠标点击进行相应,首先如何获得鼠标点击呢?

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

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

    方式二:就是事件驱动模型目前大部分的UI编程都是事件驱动模型,如很多UI平台都会提供onClick()事件,这个事件就代表鼠标按下事件。事件驱动模型大体思路如下:

    1. 有一个事件(消息)队列;

    2. 鼠标按下时,往这个队列中增加一个点击事件(消息);

    3. 有个循环,不断从队列取出事件,根据不同的事件,调用不同的函数,如onClick()、onKeyDown()等;

    4. 事件(消息)一般都各自保存各自的处理函数指针,这样,每个消息都有独立的处理函数;如图:

     

    4. 事件驱动处理库

    • select

    • poll

    • epoll

    • libev

    5.效率比较 

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

     

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

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

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

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

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

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

    事件驱动机制跟消息驱动机制相比

    消息驱动和事件驱动很类似,都是先有一个事件,然后产生一个相应的消息,再把消息放入消息队列,由需要的项目获取。他们的区别是消息是谁产生的

    消息驱动:鼠标管自己点击不需要和系统有过多的交互,消息由系统(第三方)循环检测,来捕获并放入消息队列。消息对于点击事件来说是被动产生的,高内聚。

    事件驱动:鼠标点击产生点击事件后要向系统发送消息“我点击了”的消息,消息是主动产生的。再发送到消息队列中。

     

    事件:按下鼠标,按下键盘,按下游戏手柄,将U盘插入USB接口,都将产生事件。比如说按下鼠标左键,将产生鼠标左键被按下的事件。

    消息:当鼠标被按下,产生了鼠标按下事件,windows侦测到这一事件的发生,随即发出鼠标被按下的消息到消息队列中,这消息附带了一系列相关的事件信息,比如鼠标哪个键被按了,在哪个窗口被按的,按下点的坐标是多少?如此等等。

    注意:

    1. 要理解事件驱动和程序,就需要与非事件驱动的程序进行比较。实际上,现代的程序大多是事件驱动的,比如多线程的程序,肯定是事件驱动的。早期则存在许多非事件驱动的程序,这样的程序,在需要等待某个条件触发时,会不断地检查这个条件,直到条件满足,这是很浪费cpu时间的。而事件驱动的程序,则有机会释放cpu从而进入睡眠态(注意是有机会,当然程序也可自行决定不释放cpu),当事件触发时被操作系统唤醒,这样就能更加有效地使用cpu.
    2. 再说什么是事件驱动的程序。一个典型的事件驱动的程序,就是一个死循环,并以一个线程的形式存在,这个死循环包括两个部分,第一个部分是按照一定的条件接收并选择一个要处理的事件,第二个部分就是事件的处理过程。程序的执行过程就是选择事件和处理事件,而当没有任何事件触发时,程序会因查询事件队列失败而进入睡眠状态,从而释放cpu。
    3. 事件驱动的程序,必定会直接或者间接拥有一个事件队列,用于存储未能及时处理的事件。
    4. 事件驱动的程序的行为,完全受外部输入的事件控制,所以,事件驱动的系统中,存在大量这种程序,并以事件作为主要的通信方式。
    5. 事件驱动的程序,还有一个最大的好处,就是可以按照一定的顺序处理队列中的事件,而这个顺序则是由事件的触发顺序决定的,这一特性往往被用于保证某些过程的原子化。
    6. 目前windows,linux,nucleus,vxworks都是事件驱动的,只有一些单片机可能是非事件驱动的。


    事件模式耦合高,同模块内好用;消息模式耦合低,跨模块好用。事件模式集成其它语言比较繁琐,消息模式集成其他语言比较轻松。事件是侵入式设计,霸占你的主循环;消息是非侵入式设计,将主循环该怎样设计的自由留给用户。如果你在设计一个东西举棋不定,那么你可以参考win32的GetMessage,本身就是一个藕合度极低的接口,又足够自由,接口任何语言都很方便,具体应用场景再在其基础上封装成事件并不是难事,接口耦合较低,即便哪天事件框架调整,修改外层即可,不会伤经动骨。而如果直接实现成事件,那就完全反过来了。

     

    什么是数据驱动编程

    正题

    作者在介绍Unix设计原则时,其中有一条为“表示原则:把知识叠入数据以求逻辑质朴而健壮”。结合之前自己的一些经验,我对这个原则很有共鸣,所以先学习了数据驱动编程相关的内容,这里和大家分享出来和大家一起讨论。

    核心

    数据驱动编程的核心出发点是相对于程序逻辑,人类更擅长于处理数据。数据比程序逻辑更容易驾驭,所以我们应该尽可能的将设计的复杂度从程序代码转移至数据。

    真的是这样吗?让我们来看一个示例。假设有一个程序,需要处理其他程序发送的消息,消息类型是字符串,每个消息都需要一个函数进行处理。第一印象,我们可能会这样处理: 

    void msg_proc(const char *msg_type, const char *msg_buf) 
    { 
        if (0 == strcmp(msg_type, "inivite")) 
        { 
            inivite_fun(msg_buf); 
        } 
        else if (0 == strcmp(msg_type, "tring_100")) 
        { 
            tring_fun(msg_buf); 
        } 
        else if (0 == strcmp(msg_type, "ring_180")) 
        { 
            ring_180_fun(msg_buf); 
        } 
        else if (0 == strcmp(msg_type, "ring_181")) 
        { 
            ring_181_fun(msg_buf); 
        } 
        else if (0 == strcmp(msg_type, "ring_182")) 
        { 
            ring_182_fun(msg_buf); 
        } 
        else if (0 == strcmp(msg_type, "ring_183")) 
        { 
            ring_183_fun(msg_buf); 
        } 
        else if (0 == strcmp(msg_type, "ok_200")) 
        { 
            ok_200_fun(msg_buf); 
        }
    
        。。。。。。 
        else if (0 == strcmp(msg_type, "fail_486")) 
        { 
            fail_486_fun(msg_buf); 
        } 
        else 
        { 
            log("未识别的消息类型%s\n", msg_type); 
        } 
    } 


    上面的消息类型取自sip协议(不完全相同,sip协议借鉴了http协议),消息类型可能还会增加。看着常常的流程可能有点累,检测一下中间某个消息有没有处理也比较费劲,而且,没增加一个消息,就要增加一个流程分支。

    按照数据驱动编程的思路,可能会这样设计: 

    typedef void (*SIP_MSG_FUN)(const char *);
    
    typedef struct __msg_fun_st 
    { 
        const char *msg_type;//消息类型 
        SIP_MSG_FUN fun_ptr;//函数指针 
    }msg_fun_st;
    
    msg_fun_st msg_flow[] = 
    { 
            {"inivite", inivite_fun}, 
            {"tring_100", tring_fun}, 
            {"ring_180", ring_180_fun}, 
            {"ring_181", ring_181_fun}, 
            {"ring_182", ring_182_fun}, 
            {"ring_183", ring_183_fun}, 
            {"ok_200", ok_200_fun},
    
            。。。。。。 
            {"fail_486", fail_486_fun} 
    };
    
    void msg_proc(const char *msg_type, const char *msg_buf) 
    { 
        int type_num = sizeof(msg_flow) / sizeof(msg_fun_st); 
        int i = 0;
    
        for (i = 0; i < type_num; i++) 
        { 
            if (0 == strcmp(msg_flow[i].msg_type, msg_type)) 
            { 
                msg_flow[i].fun_ptr(msg_buf); 
                return ; 
            } 
        } 
        log("未识别的消息类型%s\n", msg_type); 
    } 

     

    数据驱动优势

    1、可读性更强,消息处理流程一目了然。

    2、更容易修改,要增加新的消息,只要修改数据即可,不需要修改流程。

    3、重用,第一种方案的很多的else if其实只是消息类型和处理函数不同,但是逻辑是一样的。下面的这种方案就是将这种相同的逻辑提取出来,而把容易发生变化的部分提到外面。

    隐含在背后的思想

    很多设计思路背后的原理其实都是相通的,隐含在数据驱动编程背后的实现思想包括:

    1、控制复杂度。通过把程序逻辑的复杂度转移到人类更容易处理的数据中来,从而达到控制复杂度的目标。

    2、隔离变化。像上面的例子,每个消息处理的逻辑是不变的,但是消息可能是变化的,那就把容易变化的消息和不容易变化的逻辑分离。

    3、机制和策略的分离。和第二点很像,本书中很多地方提到了机制和策略。上例中,我的理解,机制就是消息的处理逻辑,策略就是不同的消息处理(后面想专门写一篇文章介绍下机制和策略)。

    数据驱动可以用来做什么:

    如上例所示,它可以应用在函数级的设计中。

    同时,它也可以应用在程序级的设计中,典型的比如用表驱动法实现一个状态机(后面写篇文章专门介绍)。

    也可以用在系统级的设计中,比如DSL(这方面我经验有些欠缺,目前不是非常确定)。

    它不是什么:

    1、 它不是一个全新的编程模型:它只是一种设计思路,而且历史悠久,在unix/linux社区应用很多;

    2、它不同于面向对象设计中的数据:“数据驱动编程中,数据不但表示了某个对象的状态,实际上还定义了程序的流程;OO看重的是封装,而数据驱动编程看重的是编写尽可能少的代码。”

    书中的值得思考的话:

    数据压倒一切。如果选择了正确的数据结构并把一切组织的井井有条,正确的算法就不言自明。编程的核心是数据结构,而不是算法。——Rob Pike

    程序员束手无策。。。。。只有跳脱代码,直起腰,仔细思考数据才是最好的行动。表达式编程的精髓。——Fred Brooks

    数据比程序逻辑更易驾驭。尽可能把设计的复杂度从代码转移至数据是个好实践。——《unix编程艺术》作者。

     

    转载自:学时网 » 事件驱动编程、消息驱动编程、数据驱动编程

    展开全文
  • 此资料包里面包括了Windows驱动编程和Windows_API_参考资料,对于想在Windows系统底层进行开发和研究的同学,此资料包是个不错的选择
  • windows硬件驱动编程教程
  • windows驱动编程大全

    2012-10-26 17:16:49
    Windows 2000XP WDM设备驱动程序开发 第二版.pdf window2000内部揭密.pdf Microsoft+Windows驱动程序模型设计.pdf
  • ecard驱动包 深圳德卡科技有限公司 刷卡专用
  • PCI modem Windows_SM56_6.12.07_DFV Cis32
  • FM芯片QN8025驱动程序
  • 楚狂人写的一本关于驱动开发的很好的学习教程,里面的知识点很多。对初学者很好帮助。
  • 完整的零基础学习windows驱动编程(内附源码)。内核编程环境配置;串口过滤、键盘过滤;磁盘虚拟;磁盘过滤;文件系统过滤与监控;文件系统透明加密;文件系统微过滤;网络传输层过滤;NDIS协议驱动;NDIS小端口...
  • windows上的PCI驱动,包括驱动程序入口,IO控制处理等。
  • driver for POS 58 printer
  • Windows驱动编程入门.pdf
  • 1)WDF编程框架:面向对象和事件机制 2)WDF重要对象:驱动对象、设备对象、IO队列、IO请求、等 3)事件回调函数:从派遣函数到事件回调函数的原理流程解析 4)WDF过滤驱动:掌握WDF对IRP的处理,以及过滤驱动的应用...
  • 驱动精灵2009 驱动更新 备份 还原 软件
  • 收银系统、POS系统等的莹浦通WP-t800 2.94版本的驱动程序
  • Windows驱动编程教程

    2014-03-13 10:11:07
    Windows驱动编程教程简介:本书www.tomzw.com编写非常适合熟悉Windows 应用编程的读者转向驱动开发。所有的内容都从最基础的编程方法入手。介绍相关的内核API,然后举出示范的例子。这本书只有不到70 页,是一本非常...
  • 寒江独钓-Windows内核安全编程(完整版)
  • windows驱动视频教程第六课!
  • windows内核驱动编程基础 详细介绍windows内核驱动的编程技术
  • 针对嵌入式 GUI中使用事件驱动编程机制实现窗口和控件的开发进行了讨论,分析了自主开发的TBGUI的体系结构和特点,提供了一种完全实用的嵌入式系统中的类 Windows图形用户界面。 TBGUI适合以单片机为主的 8位、16位...
  • Windows2000设备驱动程序开发大全
  • 通过更改win10系统环境,让EZP2010编程器在win10环境下运行,压缩包中含有适合EZP2010win10驱动文件,ezp2011编程器工具,ezp2010 v3固件升级包,文本详细介绍如何操作
  • Windows虚拟鼠标键盘驱动 完整源代码包含visual studio项目文件
  • 本书的前身是《天书夜读——从汇编语言到Windows内核编程》和《寒江独钓——Windows内核安全编程》。与Windows客户端安全软件开发相关的驱动程序开发是本书的主题。书中的程序使用环境从32位到64位,从Windows XP到...
  • Windows编程Windows驱动开发环境搭建

    千次阅读 2020-07-02 09:38:48
    作为一个编写Windows程序的开发人员,对Windows驱动开发 并非必需要掌握,但是掌握 Windows驱动开发对Windows程序开发人员却有极大的好处。一个直观的感受 程序操作权限更大了,因为处在内核层了嘛。应该可以写更...

    前言

    作为一个编写Windows程序的开发人员,对Windows驱动开发 并非必需要掌握,但是掌握 Windows驱动开发对Windows程序开发人员却有极大的好处。一个直观的感受 程序操作权限更大了,因为处在内核层了嘛。应该可以写更厉害的外挂,普通Windows程序写个辅助完全是没问题的,但是涉及到数据修改突破游戏程序的一些限制 必须用更高权限的内核驱动了。

    开始学习Windows驱动开发,第一步当然是环境搭建了。因为笔者也在驱动环境搭建上也吃过亏,所以这里进行记录和分享,当然这里也是集众家之长了。

    其实笔者在一开始学Windows程序开发的时候 搭过一次驱动开发环境,当时直接用vs2015还是vs2017 忘了,使用WDK10,搭了好几周 都没搭成功,最后 无奈放弃。总结下失败原因,WDK10的版本众多 而且还要和当前 操作系统一一对应,而且win10 又经常更新,当时调试机也是用的win10版本,笔者电脑配置也不行 开win10虚拟机也吃力。

    这里笔者建议初学者 不要一开始 就WDK10 和 VS集成开发 调试。先使用windbg 把双机调试搞起来了 再说。其实vs集成开发调试 也是调用的windbg。这里顺带说一下 WDK版本和操作系统版本关系。WDK 7600_1 在主机最低Win7安装,编译出来的驱动 最低支持到Win XP,VS未集成。WDK8.1 在主机最低Win8上安装,编译出来的驱动最低支持Win Visa,VS2013开始集成。WDK 10具体版本 就具体细化了 编译出来的驱动最低支持到Win7。基本上做Win开发 都是以 Win XP作为 支持的最后底线,所以一般 我们用WDK7即可了

    笔者这里环境是 主机Win10 + WDK7600_1 + 调试机Win XP Sp3

    步骤

    步骤一

    在win10上安装 WDK7600_1,将GRMWDK_EN_7600_1.ISO 解压安装即可。百度云下载链接

    链接:https://pan.baidu.com/s/1ldYMIIn6837iq2IYUpNSqg
    提取码:3lex
    或者 网上搜索,都可以找到。

    步骤二

    使用VMware安装Win XP Sp3虚拟机,安装完毕后,在C:\boot.ini中添加调试模式启动选项。添加后如下:

    [boot loader]
    timeout=30
    default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
    [operating systems]
    multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /noexecute=optin /fastdetect
    multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /noexecute=optin /fastdetect /debug /debugport=com1 /baudrate=115200
    
    

    此时如果重启,显示页面应该如下,说明boot.ini配置好了。

    在这里插入图片描述

    随后添加串行端口。用于主机与调试机通信使用的。

    在这里插入图片描述

    步骤三

    配置WinDbg

    File -> Kernel Debugging -> COM 进行如下配置,端口和波特率要和 虚拟机配置一样。

    在这里插入图片描述

    也可以 将windbg.exe 发送到桌面快捷方式,在快捷方式 -> 属性-> 快捷方式 -> 目标 空格后添加如下参数,这样以后 双击 就开始会连接调试机。

    // 目标程序后面 添加如下参数
     -b -k com:port=\\.\pipe\com_1,baud=115200,pipe
    // 下面是笔者的目标
    D:\WinDDK\7600.16385.1\Debuggers\windbg.exe -b -k com:port=\\.\pipe\com_1,baud=115200,pipe
    

    连接测试

    在步骤二、三 完全配置好了就可以 测试 双机调试 是否连通通了,重启 Win Xp Sp3,可以在启动项 那里来回切,这样就停在那里了。此时 调试机 的串口已经启动了,此时可以进行步骤三 进行连接了。

    在这里插入图片描述

    此时可以点击 WinXp 调试启动了。

    此时WinDbg如下:

    在这里插入图片描述

    此时,虚拟机也会被暂停,在kd> g 继续,测试虚拟机正常启动。

    在虚拟机中可以加载驱动进行测试,看windbg是否有输出,调试机 连接 windbg 调试,请看步骤五。

    在这里插入图片描述

    步骤四

    配置系统内核符号表。笔者用的Win XP Sp3 x86版本,下的符号表 WindowsXP-KB936929-SP3-x86-symbols-full-ENU.exe 这个,本来微软可以在线获取符号表,笔者自己测试 貌似没起效果 没有进行在线获取。百度云链接:

    链接:https://pan.baidu.com/s/1ABA8qcealpBKr_Op2QF_Pw
    提取码:wmi3

    笔者这里选择的安装目录时在 C:\symbols。这里一定要注意,我们配置符号表路径 不能直接是根目录,一定得 具体到下面的子目录 才是 pdb路径。

    在这里插入图片描述

    在 系统环境路径配置如下:

    在这里插入图片描述

    _NT_SYMBOL_PATH
    F:\Book\Windows\Windows内核安全与驱动开发随书源代码\first\objchk_wxp_x86\i386;C:\Symbols\acm;C:\Symbols\ax;C:\Symbols\cnv;C:\Symbols\com;C:\Symbols\cpl;C:\Symbols\dic;C:\Symbols\dll;C:\Symbols\drv;C:\Symbols\ds;C:\Symbols\exe;C:\Symbols\iec;C:\Symbols\ime;C:\Symbols\ocx;C:\Symbols\scr;C:\Symbols\sys;C:\Symbols\tpl;C:\Symbols\tsp;C:\Symbols\wpc;SRV*C:\Symbols_cache*http://msdl.microsoft.com/download/symbols;
    

    笔者这里是 把测试的sys驱动的 pdb路径配置上,然后再才是本地Win XP Sp3系统符号表,最后再才是 在线获取符号表配置(笔者这里测试貌似不起效果)。

    配置完了后,可以重写进行连接测试,走到 kd> 命令行处,或者如果在运行时直接 Debug -> Break 也会进行中断到 kd> 命令行处,我们进行一些简单测试。

    // 1、查看设置的符号表路径,如果查找出来不是签名配置的路径,可以在WinDbg->File->Symbol File Path 将路径路径拷贝进入勾上Reload框 然后点击OK。 就会重新加载符号文件路径了。
    kd> .sympath	
    // 2、查看相应的模块信息,如果能查找系统模块pdb说明 我们配置系统符号表没问题
    kd> !lmi ntkrpamp
    

    在这里插入图片描述

    步骤五

    我们准备一个 测试用的sys,看能否进入断点调试。我们只需要找一个可以加载装载驱动的软件就可以了。这里笔者用 Driver Monitor软件来加载驱动。

    这里准备一个sys文件,这里笔者直接用<< Windows内核安全与驱动开发 >> 随书源代码中的 first例子。使用 x86 Free Build Environment(安装好wdk后,在启动菜单可以找到) 进行编译,cd 切换到first.sys目录,然后build。会生成如下的 first.pdb和first.sys。

    first.c

    ///
    /// @file first.c
    /// @author crazy_chu
    /// @date2008-11-1
    /// 
    
    #include <ntddk.h>
    	
    // 提供一个Unload函数只是为了
    VOID DriverUnload(PDRIVER_OBJECT driver)
    {
    	// 但是实际上我们什么都不做,只打印一句话:
    	DbgPrint("first: Our driver is unloading…\r\n");
    }
    
    // DriverEntry,入口函数。相当于main。
    NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
    {
    #if DBG
           _asm int 3
    #endif
    	// 这是我们的内核模块的入口,可以在这里写入我们想写的东西。
    	// 我在这里打印一句话。因为”Hello,world” 常常被高手耻笑,所以
    	// 我们打印一点别的。
    	DbgPrint("first: Hello, my salary!\r\n");
    
    	// 设置一个卸载函数便于这个函数能退出。
    	driver->DriverUnload = DriverUnload;
    	return STATUS_SUCCESS;
    }
    
    

    在这里插入图片描述

    这个路径 要添加到 环境变量_NT_SYMBOL_PATH 或者 WDK中的 sympath中去。

    我们把first.sys 拷贝到 虚拟机中,然后使用 monitor,File ->Open Driver first.sys ,然后再File->Start Driver 这时会去装载驱动,然后再File->Stop Driver 这时会去 卸载驱动。

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    总结

    作为初学者,建议先把 windbg双机调试模式 搞起来这才是王道,vs集成驱动开发可以后面再搞。笔者认为 win10 + wdk7 + win xp sp3 双机调试也是最省配置的。

    展开全文
  • [Windows.7.设备驱动程序开发].(Windows.7.Device.Driver).Reeves

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 130,618
精华内容 52,247
关键字:

windows的事件驱动编程