事件处理的背后--综述

前言

事件处理是每个计算机系统与外设进行交互都必须解决的问题,它存在于各种开发场景中,比如iOS开发中的RunLoop,Android开发中的Looper,前端开发中的EventLoop都是相似的事件处理库。因为偏向底层,同时又是开发中的关键概念,所以有很多人对它进行过阐述,但那些文章多是基于苹果的开发文档,或者开源的代码分析而来,很少有跳出这些具体的实现,站在整个计算机系统的层面来讨论的。最近在看CSAPP,回想学过的单片机知识,发现这些机制和中断之间存在某种联系,在和做嵌入式开发的同学交流之后更加坚定了我的判断。搜集整理了许多资料之后,说说我的个人理解。RunLoop,Looper或者EventLopp等等都是一种事件处理机制,这种事件处理机制是普遍存在的,我们使用的几乎所有应用程序,QQ,微信,Tomcat,Nginx等,它们之所以能在启动后一直运行,并且可以在单线程的情况下,异步去接收各种事件并处理,就因为有了这样一套机制。而事件可以产生于由处理器内(比如Timer)或者处理器外(比如点击屏幕),那么点击了触摸屏之后发生了什么?事件是怎样被处理器发现并处理的?操作系统怎么处理CPU发生的中断的?上层的应用程序是怎样获取这些中断事件的?应用程序获取了这些中断后怎样找到合适的处理者进行处理?。为了回答这些问题,我决定写一个系列的文章来探讨,本文将从不含操作系统的裸机–单片机中的键盘事件来介绍中断,然后介绍含有操作系统的中断处理,最后介绍事件处理机制,RunLoop和线程等内容,欢迎大家留言,讨论,指正。

综述

我们以触摸事件为例来谈谈事件的处理流程:

  1. 我们的手指点击屏幕,屏幕会产生高低电平
  2. 高低电平的连接线和微处理器的中断源相连接,这会产生一个中断
  3. 处理器内部有一个中断向量表,这个中断向量表会指向中断产生之后所执行代码的具体地址,然后CPU设置PC值跳转到相应的处理程序
  4. 操作系统收集这个中断放入一个event queue中(操作系统是面对硬件的第一层软件,所以它会提供一个中断的统一处理机制)
  5. 操作系统根据某中标标识找到处理事件的合适应用程序
  6. 操作系统利用IPC等机制将这个事件消息发送给想相应的应用程序(如果应用程序处理休眠状态,那么会将此程序唤醒)
  7. 应用程序会利用事件处理模型(EventLoop,RunLoop,Looper),通过系统调用从操作系统获取事件并处理
  8. 应用程序在收到事件之后会找到事件触发事件的源头和事件处理者。在iOS系统中会先传递给UIAppliction单例,然后再根据视图的层级关系利用hitTest:withEvent:pointInside:withEvent:找到事件产生的视图
  9. 找到事件源视图之后就会根据Resoponse Chain来找到事件的处理者,对事件进行相应的处理

在接下来的系列文章里,将会从:中断操作系统的中断处理事件处理模型RunLoop的实现原理等几方面做以论述。