【IO模型】
Stevens一共有5种IO Model:
1.blocking IO 阻塞 -------------常见的网络阻塞状态:accept、recv、recvfrom
2.nonblocking IO 非阻塞
3.IO multiplexing IO多路复用
4.signal driven IO 信号驱动IO
5.asynchronous IO 异步IO
由signal driven IO(信号驱动IO)在实际中并不常用,所以主要介绍剩下的四种IO Model(IO多路复用、异步IO)。

(阻塞IO模型)

1 import socket 2 3 server = socket.socket() 4 server.bind(('127.0.0.1', 6969)) 5 server.listen(5) 6 7 while True: 8 conn, addr = server.accept() 9 while True: 10 try: 11 data = conn.recv(1024) 12 if len(data) == 0: break 13 print(data) 14 conn.send(data.upper()) 15 except ConnectionResetError as e: 16 break 17 conn.close() 18 # 在服务端开设多进程或者多线程,其实还是没有解决IO问题,该等的地方还是在等,没有规避,只不过多个人等待的彼此过程中互不干扰
(非阻塞IO模型)
虽然非阻塞IO看起来非常的厉害,但该模型会长时间占用CPU不干活,让CPU处于空转的状态,

1 服务端 2 3 import socket, time 4 5 server = socket.socket() 6 server.bind(('127.0.0.1', 8888)) 7 server.listen(5) 8 server.setblocking(True) # 设置阻塞 9 # 如果()内为False,则表示将所有的网络阻塞变为非阻塞, 10 11 r_list = [] 12 del_list = [] 13 while True: 14 try: 15 conn, addr = server.accept() # 立马阻塞 16 r_list.append(conn) 17 except BlockingIOError as e: 18 # time.sleep(2) 19 # print('列表的长度:',len(r_list)) 20 # print('做其他事情') 21 for conn in r_list: 22 try: 23 data = conn.recv(1024) # 没有消息 报错 24 if len(data) == 0: # 客户端断开链接 25 conn.close() 26 # 将无用的conn从r_list删除 27 del_list.append(conn) 28 continue
conn.send(data.upper()
29 except BlockingIOError: 30 continue 31 except ConnectionResetError: 32 conn.close() 33 del_list.append(conn) 34 # 挥手无用链接 35 for conn in del_list: 36 r_list.remove(conn) 37 del_list.remove(conn) 38 39 ================================= 40 客户端 41 42 import socket 43 44 client = socket.socket() 45 client.connect(('127.0.0.1', 8888)) 46 47 while True: 48 msg = input('>>>:') 49 client.send(b'hello world') 50 data = client.recv(1024) 51 print(data)
(多路复用)
当监管的对象只有一个的时候 其实IO多路复用连阻塞IO都比比不上!!!但是IO多路复用可以一次性监管很多个对象
监管机制是操作系统本身就有的 如果你想要用该监管机制(select)需要你导入对应的selectors模块
总结:
监管机制由很多
select机制 window linux都有
poll机制 只有linux有,poll机制和select机制基本一样,都可以监管多个对象,但是poll机制没有最大连接数的限制,在监管的时候肯会出现延时相应
epoll机制 只有linux有,给每个监管机制对象都绑定了一个回调机制,一旦有响应,回调机制立马发起提醒

1 服务端 2 3 import socket, select 4 5 server = socket.socket() 6 server.bind(('127.0.0.1', 8001)) 7 server.listen(5) 8 server.setblocking(False) # 设置阻塞 9 read_list = [server] 10 while True: 11 r_list, w_list, x_list, = select.select(read_list, [], []) 12 for i in r_list: 13 if i is server: 14 conn, addr = i.accept() 15 # 也该添加到监管的队列中 16 read_list.append(conn) 17 else: 18 res = i.recv(1024) 19 if len(res) == 0: 20 i.close() 21 # 将无效的监管对象移除 22 read_list.remove(i) 23 continue 24 print(res) 25 i.send(b'OK') 26 27 28 ============================================ 29 客户端 30 31 import socket 32 33 client = socket.socket() 34 client.connect(('127.0.0.1', 8001)) 35 36 while True: 37 38 client.send(b'hello world') 39 data = client.recv(1024) 40 print(data)
(异步IO)
异步IO模型是所有模型中效率最高的 也是使用最广泛的相关的模块和框架
模块:asyncio模块
异步框架:sanic、tronado、twisted
速度快

1 import threading, asyncio 2 3 4 @asyncio.coroutine 5 def hello(): 6 print('Hello world!%s' % threading.current_thread()) 7 # 异步调用asyncio.sleep(1) 8 yield from asyncio.sleep(1) 9 print('Hello world%s' % threading.current_thread()) 10 11 12 loop = asyncio.get_event_loop() 13 tasks = [hello(), hello()] 14 loop.run_until_complete(asyncio.wait(tasks)) 15 loop.close()
总结

浙公网安备 33010602011771号