- 事件驱动
gevent协程可实现自动切换,协程在遇到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. 事件(消息)一般都各自保存各自的处理函数指针,这样,每个消息都有独立的处理函数;
- 事件驱动模型
# 网络编程范式 根据事件发生进行相应处理。
# 其他范式:单线程同步、多线程编程。
当一个事件进入,放入到列表队列内注册任务,如果这个事件处理需要5秒钟,协程会在去处理第二个事件也放入队列内,通过一个不断检测事件的线程来处理相应的事件。这个处理机制是由外部事件如鼠标,键盘来产生,他的特点是包含一个事件循环,当外部事件发生时使用回调机制来触发相应的处理。回调主要是执行线程处理完毕时在次进行的理,同时告诉协程这个事情处理完毕,事件进入注册任务时同时会加一个回调函数,这个回调内容可以自定义。
- 编程范式
红色(任务1) 、蓝色(任务2) 、黄色(任务3) 、灰色(IO处理)
这里我们用到了三种编程范式,分别是线程,进程,协程,可以清晰的看出线程用的时间最长效率低,进程虽然效率高但消耗资源,协程分开切换io处理,提高效率并节省资源,将CPU与IO单独进行处理,CPU只负责计算,通过一个线程把IO交给操作系统,并回调结果与协程在次交互。