Day14 - Python基础14 事件驱动模型、IO模型
本节内容:
1:事件驱动模型
2:IO模型前戏准备
3:4种IO模型
1:事件驱动模型
传统的编程是如下线性模式的:
开始--->代码块A--->代码块B--->代码块C--->代码块D--->......--->结束
每一个代码块里是完成各种各样事情的代码,但编程者知道代码块A,B,C,D...的执行顺序,唯一能够改变这个流程的是数据。输入不同的数据,根据条件语句判断,流程或许就改为A--->C--->E...--->结束。每一次程序运行顺序或许都不同,但它的控制流程是由输入数据和你编写的程序决定的。如果你知道这个程序当前的运行状态(包括输入数据和程序本身),那你就知道接下来甚至一直到结束它的运行流程。
对于事件驱动型程序模型,它的流程大致如下:
开始--->初始化--->等待
与上面传统编程模式不同,事件驱动程序在启动之后,就在那等待,等待什么呢?等待被事件触发。传统编程下也有“等待”的时候,比如在代码块D中,你定义了一个input(),需要用户输入数据。但这与下面的等待不同,传统编程的“等待”,比如input(),你作为程序编写者是知道或者强制用户输入某个东西的,或许是数字,或许是文件名称,如果用户输入错误,你还需要提醒他,并请他重新输入。事件驱动程序的等待则是完全不知道,也不强制用户输入或者干什么。只要某一事件发生,那程序就会做出相应的“反应”。这些事件包括:输入信息、鼠标、敲击键盘上某个键还有系统内部定时器触发。
事件驱动模型在前端的时候会大量的使用这个概念。
事件驱动模型也是一种编程思想
如 面向过程,面向对象 ,面向函数这些都是编程思想
事件驱动的执行流程,
- 1内部维护一个事件列表 ,
- 2当发生一个事件就从列表appent一个事件,
- 3 有一个线程一直从事件列表取事件,然后执行对应事件的函数
2:IO模型前戏准备
在进行解释之前,首先要说明几个概念:
- 用户空间和内核空间
- 进程切换
- 进程的阻塞
- 文件描述符
- 缓存 I/O
3.IO模型
一、阻塞IO模型
在linux中,默认情况下所有的socket都是blocking,一个典型的读操作流程大概是这样:
解析:当socket—server应用程序发送accept进行了系统调用就一直阻塞住整个程序,直到有人链接为止。
大白话 :
阻塞IO 去车站买票一直排队阻塞,直到买到票为止
##########server############
import socket sk = socket.socket()
sk.bind(('127.0.0.1',))
sk.listen() while :
conn,addr = sk.accept() ##阻塞住
while :
data = conn.recv() ##阻塞住 ##########client######### import socket
cs = socket.socket()
cs.connect(('127.0.0.1',))
while :
data = input('plz input something:')
cs.send(b'%s'%data)
二、 non-blocking IO(非阻塞IO)
linux下,可以通过设置socket使其变为non-blocking。当对一个non-blocking socket执行读操作时,流程是这个样子:
大白话:
非阻塞IO 去车站买票车站进行排号,每隔一段时间回来看是不是轮到自己了,每一次间隔的时间就可以去做其他的事情了。
存在缺点:
- 每一次去内存看数据是否存在,发了太多的系统调用了
- 数据没有实时。
import time
import socket
sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sk.setsockopt
sk.bind(('127.0.0.1',))
sk.listen()
sk.setblocking(False) ##通过设置setblocking(False)就不会进行阻塞,去执行下面的else代码
while True:
try:
print ('waiting client connection .......')
connection,address = sk.accept() # 进程主动轮询
print("+++",address)
client_messge = connection.recv()
print(str(client_messge,'utf8'))
connection.close()
except Exception as e:
print (e)
time.sleep() #############################client import time
import socket
sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM) while True:
sk.connect(('127.0.0.1',))
print("hello")
sk.sendall(bytes("hello","utf8"))
time.sleep()
break
三、IO multiplexing(IO多路复用)
IO多路复用有三种实现方式:优势 同时可以监听多个对象
- select
- poll
- epoll
流程是这个样子:
#***********************server.py
import socket
import select
sk=socket.socket()
sk.bind(("127.0.0.1",8801))
sk.listen(5)
inputs=[sk,]
while True:
r,w,e=select.select(inputs,[],[],5)
print(len(r)) for obj in r:
if obj==sk:
conn,add=obj.accept()
print(conn)
inputs.append(conn)
else:
data_byte=obj.recv(1024)
print(str(data_byte,'utf8'))
inp=input('回答%s号客户>>>'%inputs.index(obj))
obj.sendall(bytes(inp,'utf8')) print('>>',r) #***********************client.py import socket
sk=socket.socket()
sk.connect(('127.0.0.1',8801)) while True:
inp=input(">>>>")
sk.sendall(bytes(inp,"utf8"))
data=sk.recv(1024)
print(str(data,'utf8'))
select的并发聊天
r,w,e=select.select([sk,],[],[],5) ##四个参数分别是监听列表、输出列表、错误列表 5代表:就监听5秒钟,
select和阻塞IO 一样都是去进行阻塞,不过阻塞的方式不一样,select可以阻塞并监听多个的对象,当对象发生变化的时候,
对应的i 就是发生变化的对象,而且注意的select是通过水平触发的方式去发现对象是否改变。
三种多路复用的说明:
select、poll、epoll 都是IO多路复用的实现,select在unix、windows、linux 都可以用。而windows只能用select
select监听的对象最大不能超过1024 个;
而poll相当于是提高了监听的对象而已;
而epoll 是根本上解决了; select 和 epoll 的大白话,
select :考试结束交卷,要交卷拍一下桌子,而老师不知道到底是哪个 要交卷,就需要依次的遍历一个个的问过去。效率太低
epoll: 你们不管是谁要交卷,不要拍桌子了,你自报家门 说:我小虎要交卷,就直接找到了小虎收试卷。
知识点:触发方式
1:水平触发
水平触发:也就是只有高电平(1)或低电平(0)时才触发通知,只要在这两种状态就能得到通知.
上面提到的只要有数据可读(描述符就绪)那么水平触发的epoll就立即返回.
2:边缘触发
边缘触发:只有电平发生变化(高电平到低电平,或者低电平到高电平)的时候才触发通知.上面提到即使有数据
可读,但是没有新的IO活动到来,epoll也不会立即返回.
四、 Asynchronous I/O(异步IO)
异步IO的最大特点就是全程无阻塞。
linux下的asynchronous IO其实用得很少。先看一下它的流程:
大白话:
异步 就相当于你打了一个电话,说你要票,然后你就可以去干别的,直到系统打电话给你说 票到了,并把票送到你的手上。
四种IO模型的比较:
分析:
阻塞IO全程都在阻塞;
非阻塞IO只是在数据来了,才进行阻塞等待数据 ;
IO多道模型,相当于也是阻塞的,只不过是select去阻塞,且可以进行监听多个的对象。
异步IO 全程没有一丝的阻塞。
Day14 - Python基础14 事件驱动模型、IO模型的更多相关文章
- Python基础-输入输出(IO)
Python基础-输入输出(IO) 程序会有输入和输出,输入可以从标准输入或是从一个文件读入数据,程序的输出可以以一种友好可读的方式(human-readable)打印出来,或是写进一个文件,而标准输 ...
- 十四. Python基础(14)--递归
十四. Python基础(14)--递归 1 ● 递归(recursion) 概念: recursive functions-functions that call themselves either ...
- python之全栈开发——————IO模型
一:在讲IO模型之前我们首先来讲一下事件驱动模型,属于一种编程的范式,那么我们以前就是传统式编程,来看看有什么区别吧(此处为借鉴别人的) 传统的编程是如下线性模式的: 开始--->代码块A--- ...
- python 并发编程 非阻塞IO模型
非阻塞IO(non-blocking IO) Linux下,可以通过设置socket使其变为non-blocking.当对一个non-blocking socket执行读操作时,流程是这个样子: 从图 ...
- python基础(14)-反射&类的内置函数
反射 几个反射相关的函数可参考python基础(10)-匿名函数&内置函数中2.2.4反射相关 类的一些内置函数 __str__()&__repr__() 重写__str__()函数类 ...
- python基础-11 socket,IO多路复用,select伪造多线程,select读写分离。socketserver源码分析
Socket socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. sock ...
- python基础--14大内置模块(上)
python的内置模块(重点掌握以下模块) 什么是模块 常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 但其实import加载的模块分为四个通用类 ...
- python基础——14(shelve/shutil/random/logging模块/标准流)
一.标准流 1.1.标准输入流 res = sys.stdin.read(3) 可以设置读取的字节数 print(res) res = sys.stdin.readline() print(res) ...
- python基础--14大内置模块(下)
(9)正则表达式和re模块(重点模块) 在我们学习这个模块之前,我们先明确一个关系.模块和实际工作的关系. 1)模块和实际工作时间的关系 1.time模块和时间是什么关系?time模块和时间本身是没有 ...
随机推荐
- SpringCloud找不到@HystrixCommand标签
版本声明: SpringCloud:Greenwich.SR4 SpringBoot:2.1.9.RELEASE 解决方案: 添加坐标 <dependency> <groupId&g ...
- Mac环境安装非APP STORE中下载的软件,运行报错:“XXX” is damaged and can’t be opened. You should move it to the Trash. 解决办法
出现这个错误的大多数原因都是因为系统设置的问题,因为系统不信任你从其他地方下载的软件安装包,所以运行时就给你阻止了.具体的设置步骤如下: 1. 打开系统偏好设置 (System Preferences ...
- MySQL日志简介
一.MySQL日志简介 二.错误日志 作用: 记录mysql数据库的一般状态信息及报错信息,是我们对于数据库常规报错处理的常用日志. 默认位置: $MYSQL_HOME/data/ 开启方式:(MyS ...
- C#后台架构师成长之路-Orm篇体系
成为了高工,只是完成体系的熟练,这个时候就要学会啃一些框架了... 常用Orm底层框架的熟悉: 1.轻量泛型的DBHelper,一般高工都自己写的出来的 2.EF-基于Linq的,好好用 3.Keel ...
- 菜鸟刷面试题(二、RabbitMQ篇)
目录: rabbitmq 的使用场景有哪些? rabbitmq 有哪些重要的角色? rabbitmq 有哪些重要的组件? rabbitmq 中 vhost 的作用是什么? rabbitmq 的消息是怎 ...
- 第K个语法符号
在第一行我们写上一个 0.接下来的每一行,将前一行中的0替换为01,1替换为10. 给定行数 N 和序数 K,返回第 N 行中第 K个字符.(K从1开始) 例子: 输入: N = 1, K = 1输出 ...
- 观察者模式Vs发布订阅模式
1)观察者模式 观察者模式通俗的讲就是我们平事件调用(click/change等等) 大家先看这个图片.我们被观察者Subject(监听某个事件)发生改变时,观察者Observer监听到没改变做出调整 ...
- java自学-类与对象
1.面向对象和面向过程 java是一种面向对象的程序设计语言,而面向对象思想是一种程序设计思想. 这里的对象泛指现实中一切事物,每种事物都具备自己的属性和行为.面向对象思想就是在计算机程序设计过程中, ...
- Linux下部署SSM,通过启动tomcat即可运行
Linux下部署SSM项目 1. Java环境配置(JRE&JDK) 安装JDK8:sudo yum install java-1.8.0-openjdk 将操作系统配置为默认使用JDK8:s ...
- 【UR #5】怎样更有力气
Problem Description 大力水手问禅师:"大师,很多事情都需要用很大力气才能完成,而我在吃了菠菜之后力气很大,于是就导致我现在非常依赖菠菜.我很讨厌我的现状,有没有办法少吃点 ...