一 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模型)的更多相关文章

  1. Python之阻塞IO模型与非阻塞IO模型

    Python之阻塞IO模型与非阻塞IO模型 IO模型 1 阻塞IO: 全程阻塞 2 非阻塞IO: 发送多次系统调用: 优点:wait for data时无阻塞 缺点:1 系统调用太多 2 数据不是实时 ...

  2. python 并发编程 io模型 目录

    python 并发编程 IO模型介绍 python 并发编程 socket 服务端 客户端 阻塞io行为 python 并发编程 阻塞IO模型 python 并发编程 非阻塞IO模型 python 并 ...

  3. python并发之IO模型(一)

    事件驱动模型 协程:遇到IO操作就切换. 但什么时候切回去呢?怎么确定IO操作完了? 很多程序员可能会考虑使用“线程池”或“连接池”.“线程池”旨在减少创建和销毁线程的频率,其维持一定合理数量的线程, ...

  4. python基础(17)-IO模型&selector模块

    先说一下IO发生时涉及的对象和步骤.对于一个network IO (这里我们以read举例),它会涉及到两个系统对象,一个是调用这个IO的process (or thread),另一个就是系统内核(k ...

  5. python并发编程&IO模型

    一 IO模型介绍 为了更好地了解IO模型,可先回顾下:同步.异步.阻塞.非阻塞 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(n ...

  6. python并发之IO模型(二)

    blocking IO (阻塞IO) 在linux中,默认情况下所有的socket都是blocking,一个典型的读操作流程大概是这样: 当用户进程调用了recvfrom这个系统调用,kernel就开 ...

  7. Python 对象(type/object/class) 作用域 一等函数 (慕课--Python高级,IO并发 第二章)

    在python中一共有两种作用域:全局作用域和函数作用域全局作用域:在全局都有效,全局作用域在程序执行时创建,在程序执行结束时销毁:所有函数以外的区域都是全局作用域:在全局作用域中定义的变量,都属于全 ...

  8. python基础之IO模型

    IO模型分类 五种IO Model blocking IO 阻塞IO nonblocking IO 非阻塞IO IO multiplexing IO多路复用 signal driven IO 信号驱动 ...

  9. python 并发编程 IO模型介绍

    gevent 底层是怎么实现? io模型4个重要概念: 两类 一类:同步.异步 提交任务的方式 同步: 提交完任务后,在原地等待结果,拿到结果后,才执行下一行代码 #所谓同步,就是在发出一个功能调用时 ...

  10. 5月2日 python学习总结 IO模型

    IO模型 1.阻塞IO 2.非阻塞IO 3.多路复用IO 4.异步IO 一.阻塞IO blocking IO的特点就是在IO执行的两个阶段(等待数据和拷贝数据两个阶段)都被block了. 实际上,除非 ...

随机推荐

  1. SESSION会话机制解析

    Windows Session(会话)的概念 会话 session 是由代表单个用户登录会话的所有进程和系统对象组成的.其中的对象包括所有的窗口,桌面和windows stations.桌面是特定se ...

  2. FireDac 连接 SQL SERVER 2014 - LocalDB

    易博龙官方的文档没有更新,官方的文档只能连接local-db2012 微软官方关于local-db 2012的描述 如下: 但是现在我开始使用SQL SERVER LOCAL-DB 2014了,因为今 ...

  3. 《ASP.NET Core 与 RESTful API 开发实战》-- (第7章)-- 读书笔记(中)

    第 7 章 高级主题 7.2 并发 当两个用户获取同一个资源后,再同时修改该资源,就会导致并发问题 常见实现并发的方法有以下两种: 保守式并发控制,每次修改资源,都锁定资源 开放式并发控制,每次修改资 ...

  4. CF1841

    A 题意:给一个长度为 \(n\) 的全是 \(1\) 的数列,Alice 先操作,Bob 交替.每次操作选择至少两个(可以更多)相等的数字,删除它们,在序列中加入它们的和.直到有人不能操作为止,这个 ...

  5. JS leetcode 合并两个有序数组 解题分析

    壹 ❀ 引 今天做的一题是前两周博客园一粉丝在面试360时遇到的算法题,题目来自leetcode88. 合并两个有序数组,理解起来可能有些费劲,不过我尽量用图的形式给大家解释它,题目描述如下: 给你两 ...

  6. CSS浮动&定位&布局

    浮动简介 浮动最早起设计出来是为了实现文字环绕图片或者文字环绕的效果,现在浮动是主流的页面布局方式之一 float:浮动属性,值可以是left.right对应向左和向右浮动 元素浮动之后的特点 脱离文 ...

  7. 服务器网卡,10GE设备相关笔记

    连接线 铜线 六类线基本可以满足万兆, 万兆网络一般只在短程使用铜线, 或者完全不用铜线 光纤 根据带宽和距离, 分为OM2, OM3, OM4等, OM2一般用于千兆或者短距离万兆, 长距离万兆使用 ...

  8. 链表--insert

    分别是使用了二级指针和一级指针的两种方法,最后会按插入的顺序依次打印1,2,3,4 主要区别在于,使用二级指针,可以在main函数里直接用一个空的Node指针,而一级指针是在main函数里面先添加了一 ...

  9. win32 - Session 0 隔离

    在Windows XP,Windows Server 2003和Windows操作系统的早期版本中,所有服务都与登录控制台的第一个用户在同一会话中运行.该会话称为会话0.在会话0中一起运行服务和用户应 ...

  10. vscode自定义运行和调试创建launch.json文件及项目独立配置文件

    1.创建lauch.json文件 2.然后在项目目录中会自动创建.vscode的目录 3.在.vscode目录下创建settings.json项目独立配置文件 4.在settings.json中写入 ...