IO模型
IO模型--自己实现IO
目的--在单个线程里面把IO降下来
IO两个阶段
--等待数据准备
--从内核把数据拷贝到进程中
网络IO
blocking IO--阻塞IO
特点--在IO执行的两个阶段都被阻塞
nonblocking IO--非阻塞IO,利用了等待数据准备的阶段
优点--能够在等待任务的完成时间内去干其他的活
但是绝不推荐使用
非阻塞IO实现套接字通信:
from socket import * import time s = socket() s.bind(("127.0.0.1",8077)) s.listen(5) s.setblocking(False) # 参数默认是Ture--阻塞IO,设为Flase--非阻塞IO conn_l = [] while True: del_l = [] try: conn,addr = s.accept() print("%s:%s"%(addr[0],addr[1])) conn_l.append(conn) except BlockingIOError: print("没有数据") time.sleep(2) # 循环调用recv能大幅提高cpu占用率,所以睡一下 for conn in conn_l: try: data = conn.recv(1024) conn.send(data.upper()) except BlockingIOError: # 阻塞的时候直接pass掉这个连接,继续for循环下一个连接,没必要去写continue pass except ConnectionResetError: # 当客户端单方面关闭时,把已关闭的连接加到del_l列表中,等下去删除 del_l.append(conn) for conn in del_l: del_l.remove(conn) # 删除已经关闭的连接,并且关闭该连接 conn.close()
from socket import * c = socket() c.connect(("127.0.0.1",8077)) while True: msg = input(">>>") if not msg:continue c.send(msg.encode("utf-8")) data = c.recv(1024) print(data.decode("utf-8"))
IO multiplexing--多路复用IO
也是利用了等待数据准备的阶段
select模块--提供了select模型---单个进程可以同时处理多个网络连接的IO
效率最高--epoll模型(windows不支持)-- 基于Linux操作系统的,
只监测连接数不死很高的时候,效率很低
优势在于处理多个链接
多路复用IO实现套接字通信:
from socket import * import select s = socket() s.bind(("127.0.0.1",8077)) s.listen(5) s.setblocking(False) # 参数默认是Ture--阻塞IO,设为Flase--非阻塞IO read_list = [s,] # 放已经建立的连接 while True: r_l,_,_ = select.select(read_list,[],[]) # r_l,w_l,x_l = select.select(read_list,[],[]) # r_l表示准备好读的,w_l表示准备好写的,具体看select模块 for obj in r_l: if obj == s: conn,addr = obj.accept() read_list.append(conn) else: try: data = obj.recv(1024) if not data: obj.close() read_list.remove(obj) continue obj.send(data.upper()) except ConnectionResetError: obj.close() read_list.remove(obj)
from socket import * c = socket() c.connect(("127.0.0.1",8077)) while True: msg = input(">>>") if not msg:continue c.send(msg.encode("utf-8")) data = c.recv(1024) print(data.decode("utf-8"))
ansychronous IO--异步IO
充分用了等待数据准备阶段和拷贝数据阶段
signal driven IO--信号驱动IO
浙公网安备 33010602011771号