阻塞IO
用socket 一定会用到accept recv recvfrom这些方法 正常情况下 accept recv recvfrom都是阻塞的
非阻塞IO
如果setblocking(False) 整个程序就变成一个非阻塞的程序了
非阻塞的特点: 没有并发编程的机制 是一个同步的程序 程序不会在某一个连接的recv或者sk的accept上进行阻塞 缺点: 太多while True 高速运行着 大量的占用了CPU导致了资源的浪费
阻塞IO的问题: 一旦阻塞就不能做其他事情了 非阻塞IO的问题: 给CPU造成了很大的负担
import timeimport socketsk = 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 socketsk = 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)