python-day38--IO模型

一、 IO模型介绍

对于一个网络通信,IO涉及到两个阶段

  1.操作系统等数据来

  2.进程或线程等操作系统拷贝数据

记住这两点很重要,因为这些IO模型的区别就是在两个阶段上各有不同的情况。

二、阻塞IO(blocking IO)

例子:

 1 from socket import *
 2 s=socket(AF_INET,SOCK_STREAM)
 3 s.bind((‘127.0.0.1‘,8080))
 4 s.listen(5)
 5 print(‘starting..‘)
 6 while True:
 7     conn,addr=s.accept()     # accept就是IO
 8     print(addr)
 9     while True:
10         try:
11             data=conn.recv(1024)    #recv 也是IO
12             if not data : break
13             conn.send(data.upper())
14         except Exception:
15             break
16     conn.close()
17 s.close()

socket 通信服务端

 1 from socket import *
 2 c=socket(AF_INET,SOCK_STREAM)
 3 c.connect((‘127.0.0.1‘,8080))
 4
 5 while True:
 6     cmd=input(‘ss‘).strip()
 7     if not cmd:continue
 8     c.send(cmd.encode(‘utf-8‘))
 9     data=c.recv(1024)
10     print(data.decode(‘utf-8‘))

socket 通信客户端

所以,blocking IO的特点就是在IO执行的两个阶段(等待数据和拷贝数据两个阶段)都被block了。

一个简单的解决方案:

#在服务器端使用多线程(或多进程)。多线程(或多进程)的目的是让每个连接都拥有独立的线程(或进程),这样任何一个连接的阻塞都不会影响其他的连接。

该方案的问题是:

#开启多进程或都线程的方式,在遇到要同时响应成百上千路的连接请求,则无论多线程还是多进程都会严重占据系统资源,降低系统对外界响应效率,而且线程与进程本身还是没有解决IO问题,只是换了一种方式

改进方案:

#很多程序员可能会考虑使用“线程池”。“线程池”旨在减少创建和销毁线程的频率,其维持一定合理数量的线程,并让空闲的线程重新承担新的执行任务。这种技术都可以很好的降低系统开销,都被广泛应用很多大型系统,如websphere、tomcat和各种数据库等。  这种方式确实是好了些,但是还没有解决IO 问题

对应上例中的所面临的可能同时出现的上千甚至上万次的客户端请求,“线程池”或许可以缓解部分压力,但是不能解决所有问题。总之,多线程模型可以方便高效的解决小规模的服务请求,但面对大规模的服务请求,多线程模型也会遇到瓶颈,可以用非阻塞接口来尝试解决这个问题。

三 非阻塞IO(non-blocking IO)

 1 from socket import *
 2 import time
 3 s=socket(AF_INET,SOCK_STREAM)
 4 s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
 5 s.bind((‘127.0.0.1‘,8085))
 6 s.listen(5)
 7 s.setblocking(False)   #套接字里面的所有阻塞操作都会变成非阻塞
 8 print(‘starting...‘)
 9 l=[]
10 d_l=[]
11 while True:
12     try:
13         print(l)
14         conn,addr=s.accept()
15         l.append(conn)
16     except BlockingIOError:    #捕捉 accept收不到数据的时候抛出的异常
17         for conn in l:
18             try:
19                 data=conn.recv(1024)
20                 conn.send(data.upper())
21             except BlockingIOError:      #捕捉 recv收不到数据的时候抛出的异常
22                 pass
23             except ConnectionResetError:    #捕捉 客户端突然断开链接的时候抛出的异常
24                 d_l.append(conn)
25         for j in d_l:
26             j.close()
27             l.remove(j)
28         d_l=[]

服务端

 1 from socket import *
 2 c=socket(AF_INET,SOCK_STREAM)
 3 c.connect((‘127.0.0.1‘,8085))
 4
 5 while True:
 6     cmd=input(‘ss‘).strip()
 7     if not cmd:continue
 8     c.send(cmd.encode(‘utf-8‘))
 9     data=c.recv(1024)
10     print(data.decode(‘utf-8‘))

客户端

但是非阻塞IO模型绝不被推荐。

缺点:

#1. 循环调用recv()将大幅度推高CPU占用率;容易出现卡机情况
#2. 任务完成的响应延迟增大了,因为每过一段时间才去轮询一次accept操作,而任务可能在两次轮询之间的任意时间完成。这会导致整体数据吞吐量的降低。

多路复用IO(IO multiplexing)       select 模块

 1 from socket import *
 2 import time
 3 import select              #自动监听多个套接字   谁好了就可以来取了
 4 server=socket(AF_INET,SOCK_STREAM)
 5 server.bind((‘127.0.0.1‘,8085))
 6 server.listen(5)
 7 print(‘starting...‘)
 8 reads_l=[server,]
 9 while True:
10     r_l,_,_=select.select(reads_l,[],[])     #select.select返回的是 读列表里已经准备好的套接字
11     print(r_l)
12     for obj in r_l:
13         if obj == server:
14             conn,addr=obj.accept() #obj=server
15             reads_l.append(conn)
16         else:
17             try:
18                 data=obj.recv(1024) #obj=conn
19                 obj.send(data.upper())
20             except ConnectionResetError:    # 捕捉 客户端突然断开链接 造成的异常
21                 pass

服务端

 1 from socket import *
 2 c=socket(AF_INET,SOCK_STREAM)
 3 c.connect((‘127.0.0.1‘,8085))
 4
 5 while True:
 6     cmd=input(‘ss‘).strip()
 7     if not cmd:continue
 8     c.send(cmd.encode(‘utf-8‘))
 9     data=c.recv(1024)
10     print(data.decode(‘utf-8‘))

客户端

select 从流程上分析:效率不如 阻塞IO 的效率高,但是阻塞不能实现并发,

如果select只检测一个套接字,效率肯定不如阻塞IO,但是它可以同时监测多个套接字,而阻塞IO 远远不行。

select 和 非阻塞IO 比较: 非阻塞IO 是自己捕捉信号,自己处理多个套接字的,并且非常占用CPU,而select 是自动捕捉的

select监听的套接字个数不是无限多的

五、selectors模块

select,poll,epoll

epoll模型可以解决套接字个数非常多的情况(因为它的内部检测哪个套接字好了的机制和select不同(select是遍历每个套接字,看有没有好了的,而epoll是  如果哪个套接字好了,就自动跑出来)),但是windows不支持epoll模型

这三种IO多路复用模型在不同的平台有着不同的支持,而epoll在windows下就不支持,好在我们有selectors模块,帮我们默认选择当前平台下最合适的

from socket import *
import selectors   #导入selectors后,会根据你的系统 自动选择当前系统下最合适的IO模型
时间: 2024-10-09 16:25:39

python-day38--IO模型的相关文章

python开发IO模型:阻塞&非阻塞&异步IO&多路复用&selectors

一 IO模型介绍 为了更好地了解IO模型,我们需要事先回顾下:同步.异步.阻塞.非阻塞 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出的答案都可能不同,比如wiki,就认为asynchronous IO和non-blocking IO是一个东西.这其实是因为不同的人的知识背景不同,并且在讨论这个问题的时候上下文(context)也不相同.所以,

《Python》IO模型

一.IO模型介绍 为了更好地了解IO模型,我们需要事先回顾下: 同步:一件事情做完再做另一件事情 异步:同时做多件事情 阻塞:sleep.input.join.shutdown.get.acquire.wait accept.recv.recvfrom 非阻塞:strblocking(False) 用socket 一定会用到accept.recv.recvfrom这些方法 正常情况下accept.recv.recvfrom都是阻塞的 如果setblocking(False) 整个程序就变成一个非

走入计算机的第三十九天(python终结篇之IO模型)

一.IO模型 1.IO模型分类 1.阻塞IO--------blocking IO 2.非阻塞IO------nonblocking IO 3. 多路复用IO------- multiplexing 4.信号驱动IO-------signal driven IO (工作中不会使用到,只是作为了解) 5.异步IO------- asynchronous IO 2.通常情况下IO默认操作分为两个阶段(默认都是阻塞IO) 1.准备等待数据阶段,相当于请求操作系统是否有数据发送过来(调用IO操作). 2

python学习笔记(IO模型)

1.IO模型介绍: io模型一般有五种: * blocking IO         * nonblocking IO         * IO multiplexing         * signal driven IO         * asynchronous IO 但是 signal driven IO(信号驱动IO)在实际中并不常用,所以只介绍其他四中IO模型 另当IO发生时涉及的对象和步骤.对于一个network IO (这里我们以read举例),它会涉及到两个系统对象,一个是调

python基础27 -----python进程终结篇-----IO模型

一.IO模型 1.IO模型分类 1.阻塞IO--------blocking IO 2.非阻塞IO------nonblocking IO 3. 多路复用IO------- multiplexing 4.信号驱动IO-------signal driven IO (工作中不会使用到,只是作为了解) 5.异步IO------- asynchronous IO 2.通常情况下IO默认操作分为两个阶段(默认都是阻塞IO) 1.准备等待数据阶段,相当于请求操作系统是否有数据发送过来(调用IO操作). 2

Python学习【第26篇】:并发编程之IO模型

python并发编程之IO模型, 了解新知识之前需要知道的一些知识 同步(synchronous):一个进程在执行某个任务时,另外一个进程必须等待其执行完毕,才能继续执行 #所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不会返回.按照这个定义,其实绝大多数函数都是同步调用.但是一般而言,我们在说同步.异步的时候,特指那些需要其他部件协作或者需要一定时间完成的任务. #举例: #1. multiprocessing.Pool下的apply #发起同步调用后,就在原地等着任务结束,

{python之IO多路复用} IO模型介绍 阻塞IO(blocking IO) 非阻塞IO(non-blocking IO) 多路复用IO(IO multiplexing) 异步IO(Asynchronous I/O) IO模型比较分析 selectors模块

阅读目录 一 IO模型介绍 二 阻塞IO(blocking IO) 三 非阻塞IO(non-blocking IO) 四 多路复用IO(IO multiplexing) 五 异步IO(Asynchronous I/O) 六 IO模型比较分析 七 selectors模块 一 IO模型介绍 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出的答案都可能

Python开发基础-Day33 IO模型

IO模型分类 五种IO Model 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 ,会涉及到两个系统对象,一个是调用这个IO的process (or thread),另一个就是系统内核

python并发编程之IO模型,

了解新知识之前需要知道的一些知识 同步(synchronous):一个进程在执行某个任务时,另外一个进程必须等待其执行完毕,才能继续执行 #所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不会返回.按照这个定义,其实绝大多数函数都是同步调用.但是一般而言,我们在说同步.异步的时候,特指那些需要其他部件协作或者需要一定时间完成的任务. #举例: #1. multiprocessing.Pool下的apply #发起同步调用后,就在原地等着任务结束,根本不考虑任务是在计算还是在io阻

python并发编程之IO模型

了解新知识之前需要知道的一些知识 同步(synchronous):一个进程在执行某个任务时,另外一个进程必须等待其执行完毕,才能继续执行 #所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不会返回.按照这个定义,其实绝大多数函数都是同步调用.但是一般而言,我们在说同步.异步的时候,特指那些需要其他部件协作或者需要一定时间完成的任务. #举例: #1. multiprocessing.Pool下的apply #发起同步调用后,就在原地等着任务结束,根本不考虑任务是在计算还是在io阻