python高级技术(IO模型)
一 IO模型介绍
Linux环境下的network IO
* blocking IO 阻塞IO
* nonblocking IO 非阻塞IO
* IO multiplexing IO多路复用
* signal driven IO 信号驱动IO
* asynchronous IO 异步IO
由signal driven IO(信号驱动IO)在实际中并不常用,所以主要介绍其余四种IO Model。
再说一下IO发生时涉及的对象和步骤。对于一个network IO (这里我们以read举例),它会涉及到两个系统对象,一个是调用这个IO的process (or thread),另一个就是系统内核(kernel)。当一个read操作发生时,该操作会经历两个阶段:
#1)等待数据准备 (Waiting for the data to be ready)
#2)将数据从内核拷贝到进程中(Copying the data from the kernel to the process)
同步异步
阻塞非阻塞
常见的网络阻塞状态
accept
recv
recvfrom(UDP协议) send虽然也有IO行为,但是不在我们的考虑范围
send是主动性的
二 阻塞IO(blocking IO)

之前写的都是阻塞IO模型,协程除外 * 在服务端开设多个进程或者多个线程,进程池线程池,其实还是没有解决IO问题
该等的地方还是得等,没有规避
只不过多个人等待的彼此互不干扰
对应上例中的所面临的可能同时出现的上千甚至上万次的客户端请求,“线程池”或“连接池”或许可以缓解部分压力,但是不能解决所有问题。
总之,多线程模型可以方便高效的解决小规模的服务请求,但面对大规模的服务请求,多线程模型也会遇到瓶颈,可以用非阻塞接口来尝试解决这个问题。
三 非阻塞IO(non-blocking IO)

服务端:
import socket
import time server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.listen(5)
server.setblocking(False)
# 将所有的网络阻塞变为非阻塞 r_list = []
del_list = []
while True:
try:
conn, addr = server.accept()
r_list.append(conn)
except BlockingIOError as e:
# time.sleep(0.1) # 用了,就是阻塞了
# print('列表的长度:', len(r_list))
for conn in r_list:
try:
data = conn.recv(1024) # 没有消息,报错
if len(data) == 0: # 断开客户端链接
conn.close() # 关闭conn
# 将无用的conn从r_list删除
del_list.append(conn)
continue
conn.send(data.upper()) except BlockingIOError as e:
continue # 继续下一个通信对象有没有数据
except ConnectionResetError as e:
conn.close()
del_list.append(conn)
# 删除无用的链接
for conn in del_list:
r_list.remove(conn)
del_list.clear() # while True:
# try:
# data = conn.recv(1024)
# if len(data) == 0:
# break
# conn.send(data.upper())
# except ConnectionResetError as e:
# break
# conn.close()
客户端:
import socket client = socket.socket()
client.connect(('127.0.0.1', 8080)) while True:
client.send(b'hello word')
data = client.recv(1024)
print(data.decode('utf-8'))
总结:
虽然非阻塞IO可以实现并发
但是该模型会长时间占用者CPU并且不干活,让CPU不停的空转
实际应用中也不会考虑使用非阻塞IO模型
任何的技术点都有它存在的意义
实际应用或者是思想借鉴
四 多路复用IO(IO multiplexing)

服务端:
import socket
import select server = socket.socket()
server.bind(('127.0.0.1', 8081))
server.listen(5)
server.setblocking(False)
read_list = [server] # res = select.select(read_list, [], [])
'''
帮你监管
一旦有人来了 立刻给你返回对应的监管对象
'''
# print(res)
# ([<socket.socket fd=336, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080)>], [], [])
while True: # 不断的监测
r_list, w_list, x_list = select.select(read_list, [], [])
for i in read_list:
# 针对不同的对象做不同的处理
if i is server:
conn, addr = i.accept()
# 添加到监管的队列中
read_list.append(conn)
else:
res = i.recv(1024)
if len(res) == 0:
i.close()
# 将无效 的监管对象移除
read_list.remove(i)
continue
print(res)
i.send(res.upper())
客户端:
import socket client = socket.socket()
client.connect(('127.0.0.1', 8081)) while True:
client.send(b'hello word')
data = client.recv(1024)
print(data)
当监管的对象只有一个的时候,其实IO多路复用连阻塞IO都比不上
但是IO多能复用可以一次性监管很多个对象
server=socket.socket()
conn,addr=server.accept()
监管机制是操作系统本身的机制,如果想要用该监管机制(select)
需要导入对应的select模块
总结:
监管机制有很多
select机制 windows linux都有
poll机制 只在linux有 poll和select都可以监管多个对象,但poll监管的数量更多
上述select和poll机制不完美,当监管的对象特别多的时候
可能会出现极大地延时响应
epoll机制 只在linux有
它给每一个监管对象都绑定一个回调机制
一旦响应,回调机制立刻发起提醒
针对不同的操作系统需要考虑不同的监测机制,selectors模块帮你根据不同的平台自动对应相应
的监测机制
五 异步IO(Asynchronous I/O)

示例:
import threading
import asyncio @asyncio.coroutine
def hello ():
print('hello world{}'.format(threading.current_thread()))
yield from asyncio.sleep(1) # 换成真正的IO操作
print('hello world{}'.format(threading.current_thread())) loop = asyncio.get_event_loop()
tasks = [hello(), hello()]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
异步IO模型是所有模型中效率最高的,也是使用最广泛的
相关的模块和框架
模块:asyncio模块
异步框架:sanic tronado twisted
速度快
六 IO模型比较分析

经过上面的介绍,会发现non-blocking IO和asynchronous IO的区别还是很明显的。在non-blocking IO中,虽然进程大部分时间都不会被block,但是它仍然要求进程去主动的check,并且当数据准备完成以后,也需要进程主动的再次调用recvfrom来将数据拷贝到用户内存。而asynchronous IO则完全不同。它就像是用户进程将整个IO操作交给了他人(kernel)完成,然后他人做完后发信号通知。在此期间,用户进程不需要去检查IO操作的状态,也不需要主动的去拷贝数据。
python高级技术(IO模型)的更多相关文章
- Python之阻塞IO模型与非阻塞IO模型
Python之阻塞IO模型与非阻塞IO模型 IO模型 1 阻塞IO: 全程阻塞 2 非阻塞IO: 发送多次系统调用: 优点:wait for data时无阻塞 缺点:1 系统调用太多 2 数据不是实时 ...
- python 并发编程 io模型 目录
python 并发编程 IO模型介绍 python 并发编程 socket 服务端 客户端 阻塞io行为 python 并发编程 阻塞IO模型 python 并发编程 非阻塞IO模型 python 并 ...
- python并发之IO模型(一)
事件驱动模型 协程:遇到IO操作就切换. 但什么时候切回去呢?怎么确定IO操作完了? 很多程序员可能会考虑使用“线程池”或“连接池”.“线程池”旨在减少创建和销毁线程的频率,其维持一定合理数量的线程, ...
- python基础(17)-IO模型&selector模块
先说一下IO发生时涉及的对象和步骤.对于一个network IO (这里我们以read举例),它会涉及到两个系统对象,一个是调用这个IO的process (or thread),另一个就是系统内核(k ...
- python并发编程&IO模型
一 IO模型介绍 为了更好地了解IO模型,可先回顾下:同步.异步.阻塞.非阻塞 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(n ...
- python并发之IO模型(二)
blocking IO (阻塞IO) 在linux中,默认情况下所有的socket都是blocking,一个典型的读操作流程大概是这样: 当用户进程调用了recvfrom这个系统调用,kernel就开 ...
- Python 对象(type/object/class) 作用域 一等函数 (慕课--Python高级,IO并发 第二章)
在python中一共有两种作用域:全局作用域和函数作用域全局作用域:在全局都有效,全局作用域在程序执行时创建,在程序执行结束时销毁:所有函数以外的区域都是全局作用域:在全局作用域中定义的变量,都属于全 ...
- python基础之IO模型
IO模型分类 五种IO Model blocking IO 阻塞IO nonblocking IO 非阻塞IO IO multiplexing IO多路复用 signal driven IO 信号驱动 ...
- python 并发编程 IO模型介绍
gevent 底层是怎么实现? io模型4个重要概念: 两类 一类:同步.异步 提交任务的方式 同步: 提交完任务后,在原地等待结果,拿到结果后,才执行下一行代码 #所谓同步,就是在发出一个功能调用时 ...
- 5月2日 python学习总结 IO模型
IO模型 1.阻塞IO 2.非阻塞IO 3.多路复用IO 4.异步IO 一.阻塞IO blocking IO的特点就是在IO执行的两个阶段(等待数据和拷贝数据两个阶段)都被block了. 实际上,除非 ...
随机推荐
- Wamp MySQL 报错 Got a packet bigger than 'max_allowed_packet' bytes
点击电脑右下角wamp图标,然后进入mysql 下面的 my.ini 转移数据发现报这个错,字面意思允许的不够大.网上很多说法不起作用,解决方法如下: [mysqld] port=3306 expli ...
- 传统.NET应用向微服务架构迁移的实践经验--学习笔记
摘要 在本次分享中,演讲嘉宾将基于真实项目案例,剖析 .NET 应用向微服务..NET Core 等技术栈迁移的具体收益,并且分享在迁移中技术和非技术的众多考量.以及保证业务连续性的一些方法论. 议题 ...
- 探索C语言结构体:编程中的利器与艺术
欢迎大家来到贝蒂大讲堂 养成好习惯,先赞后看哦~ 所属专栏:C语言学习 贝蒂的主页:Betty's blog 1. 常量与变量 1. 什么是结构体 在C语言中本身就自带了一些数据类型,如:char,i ...
- JS 疫情宅在家,学习不能停,七千字长文助你彻底弄懂原型与原型链,武汉加油!!中国加油!!(破音)
壹 ❀ 引 原型与原型链属于老生常谈的问题,也是面试高频问题,但对于很多前端开发者来说,组织语言去解释清楚是较为困难的事情,并不是原型有多难,稍微了解的同学都知道原型这一块涉及太多知识.比如我们可以灵 ...
- NC51179 选课
题目链接 题目 题目描述 学校实行学分制. 每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分. 学校开设了 N 门的选修课程,每个学生可选课程的数量 M 是给定的. 学生选修了这 M 门课 ...
- NC16810 [NOIP1999]拦截导弹
题目链接 题目 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达 ...
- tensorflow中高维数组乘法运算
1 前言 声明:本博客里的数组乘法运算是指矩阵乘法运算,不是对应元素相乘. 在线性代数或高等代数中,我们学习了矩阵乘法,那么,什么样的高维数组才能相乘?tensorflow 又是如何定义高维数组运算规 ...
- Oracle高级队列介绍
原始链接:http://www.oracle-developer.net/display.php?id=411 oracle高级队列介绍 高级队列Advanced Queuing(AQ)在oracle ...
- 【CVE-2024-21626】容器逃逸漏洞修复
哈喽大家好,我是咸鱼. 好久不见,最近有一个很火的 CVE--runc 容器逃逸漏洞.年前的时候我们已经在测试环境进行了相关操作打算年后线上进行修复. 因为今天咸鱼才开工,所以文章也就拖到了现在 漏洞 ...
- win32-FileTimeToSystemTime的使用
#include <Windows.h> #include <iostream> #include <string> #pragma warning(disable ...
