网络io模型
内容概要
一、网络io的两个阶段
二、网络io的4种模型(模型为解决实际问题提供了一种思路)
1、网络io的两个阶段
对于执行程序来说
网络io分为两个阶段
wait code
copy code
-copy code阶段花费的时间要远远小于wait code阶段花费的时间

-套接字命令存在的io阻塞情况
-send 只有copy code阶段
-recv 有wait code阶段,也有copy code阶段
-accept 有wait code阶段,也有copy code阶段
2、网络io模型
-阻塞io模型
最开始接触的socket实现的TCP服务端就是典型的阻塞io模型
-非阻塞io模型
程序不在等待操作系统将数据交给它,无论操作系统是否拿到数据,操作系统都会返回一个结果给应用程序,应用程序根据结果,来决定执行什么功能
通过setblocking(False)来设置recv和accept为无阻塞状态
import socket server = socket.socket() server.bind(('127.0.0.1',8080)) server.listen(5) server.setblocking(False) server.getblocking() l = [] w_l = [] while 1: try: conn,addr = server.accept() l.append(conn) except BlockingIOError: # time.sleep(0.1) # print('做其他事情') # 收消息 del_l = [] for conn in l: try: data = conn.recv(1024) if not data: conn.close() del_l.append(conn) continue # conn.send(data.upper()) w_l.append((conn,data.upper())) except BlockingIOError: continue except ConnectionResetError: conn.close() continue # l.remove(conn) 不能在列表循环期间修改列表的索引 del_l.append(conn) # 发消息 del_l2 = [] for item in w_l: try: conn = item[0] data = item[1] conn.send(data) except BlockingIOError: continue except ConnectionResetError: conn.close() del_l2.append(item) continue # 回收资源 for item in del_l2: w_l.remove(item) for conn in del_l: l.remove(conn)
引用:非阻塞模型存在的问题
-循环调用recv()将大幅度推高CPU占用率;这也是我们在代码中留一句time.sleep(2)的原因,否则在低配主机下极容易出现卡机情况
-任务完成的响应延迟增大了,因为每过一段时间才去轮询一次read操作,而任务可能在两次轮询之间的任意时间完成。这会导致整体数据吞吐量的降低。
本文来自博客园,作者:口乞厂几,转载请注明原文链接:https://www.cnblogs.com/laijianwei/p/14449178.html

浙公网安备 33010602011771号