IO模型 IO多路复用
阻塞IO
用socket 一定会用到accept recv recvfrom这些方法
正常情况下 accept recv recvfrom都是阻塞的
非阻塞IO
如果setblocking(False) 整个程序就变成一个非阻塞的程序了
非阻塞的特点:
没有并发编程的机制
是一个同步的程序
程序不会在某一个连接的recv或者sk的accept上进行阻塞
缺点:
太多while True 高速运行着
大量的占用了CPU导致了资源的浪费
阻塞IO的问题:
一旦阻塞就不能做其他事情了
非阻塞IO的问题:
给CPU造成了很大的负担
import time import socket sk = socket.socket() sk.bind(('127.0.0.1',9000)) sk.setblocking(False) # 设置当前的socket server为一个非阻塞IO模型 sk.listen() conn_l = [] del_l = [] while True: try: conn,addr = sk.accept() conn_l.append(conn) # [conn1,conn2] except BlockingIOError: for conn in conn_l: # [conn1,conn2] try: conn.send(b'hello') print(conn.recv(1024)) except (NameError,BlockingIOError):pass except ConnectionResetError: conn.close() del_l.append(conn) for del_conn in del_l: conn_l.remove(del_conn) del_l.clear()
IO多路复用
io多路复用机制
select windows、mac\linux
底层是操作系统的轮询
有监听对象个数的限制
随着监听对象的个数增加,效率降低
poll mac\linux
底层是操作系统的轮询
有监听对象个数的限制,但是比select能监听的个数多
随着监听对象的个数增加,效率降低
epoll mac\linux
给每一个要监听的对象都绑定了一个回调函数
不再受到个数增加 效率降低的影响
import select # 模块 用来操作操作系统中的select(IO多路复用)机制 import socket sk = socket.socket() sk.bind(('127.0.0.1',9000)) sk.setblocking(False) sk.listen() r_lst = [sk,] print(sk) while True: r_l,_,_ = select.select(r_lst,[],[]) # r_lst = [sk,conn1,conn2,conn3] for item in r_l: if item is sk: conn, addr = sk.accept() r_lst.append(conn) else: try: print(item.recv(1024)) item.send(b'hello') except ConnectionResetError: item.close() r_lst.remove(item)