1.网络IO的两个阶段 waitdata copydata
send 先经历:copydata阶段
recv 先经历:waitdata阶段 再经历 copydata阶段 2.阻塞的IO模型
之前写的都是阻塞 无论多线程 多进程 还是进程池 线程池 3.非阻塞IO模型
非阻塞:最直接的体现 所有和读写相关的函数 都不会阻塞
意味着 在读写的时候 并不能确定目前是否可以读写 一旦不能读写就派出异常
只能使用try except 看是否可以读写
在非阻塞io中 需要不断循环询问操作是否需要处理的数据
这样一来 对应程序而言 效率确实高了
但是操作系统而言 你的程序就像一个病毒 一直强行占用cpu
当你的TCP程序 没有连接 没有数据接受 没有数据发送时 就是在做无用循环 浪费系统资源 4.多路复用 待改:有中间select recv等待结果
核心函数select
帮你检测所有的连接 找出可以被处理(可以读写)的连接
作为处理数据的一方 不再需要重复去向系统询问 select给你谁,你就用谁来处理 举例待改 举例1:迭代期间不能修改被迭代的对象
# li = [1,2,3,4,5,6]
# def mytlist_iter():
# for i in range(len(li)):
# yield li[i]
# for j in mytlist_iter():
# if j == 5:
# li.remove(5)
# d = {"a":1,"b":2}
# for k in d:
# if k == "a":
# d.pop(k) 举例2:(多路复用)
服务端:
from concurrent.futures import ThreadPoolExecutor
import socket server = socket.socket()
# 重用端口
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) server.bind(("192.168.11.210",9999)) server.listen(5) # 设置是否为阻塞 默认阻塞
server.setblocking(False) def data_handler(conn):
print("一个新连接..")
while True:
data = conn.recv(1024)
conn.send(data.upper())
# 已连接的客户端
clients = []
# 需要发送的数据
send_datas = []
# 已经发送完的 需要删除的数据
del_datas = []
# 待关闭的客户端
closed_cs = []
while True:
try:
conn,addr = server.accept()
# 切到处理数据的任务去执行
# 代码走到这里才算是连接成功
# 把连接成功的客户端存起来
clients.append(conn)
except BlockingIOError:
# print("没有可以处理的连接 就干别的活儿")
#要处理的是已经连接成功的客户端
# 接收数据
for c in clients:
try:
data = c.recv(1024)
if not data:
# 对方关闭了连接
c.close()
# 从客户端列表中删除它
closed_cs.append(c)
continue
print("收到%s" % data.decode("utf-8"))
# 现在非阻塞 send直接往缓存赛 如果缓存满了 肯定有错误 需要单独处理发送
# c.send(data.upper())
send_datas.append((c,data))
except BlockingIOError:
pass
except ConnectionResetError:
# 对方关闭了连接
c.close()
# 从客户端列表中删除它
closed_cs.append(c)
# 处理发送数据
for data in send_datas:
try:
data[0].send(data[1].upper())
# 发送成功需要删除 不能直接删除
# send_datas.remove(data)
del_datas.append(data)
except BlockingIOError:
continue
except ConnectionResetError:
# 客户端连接需要删除
data[0].close()
closed_cs.append(data[0])
# 等待发送的数据需要删除
del_datas.append(data)
# 删除无用的数据
for d in del_datas:
#从待发送的列表中删除
send_datas.remove(d)
del_datas.clear()
for c in closed_cs:
clients.remove(c)
closed_cs.clear() 客户端:
import socket c = socket.socket() c.connect(("127.0.0.1",9999)) while True:
msg = input(">>>:")
if not msg:continue
c.send(msg.encode("utf-8"))
data = c.recv(1024)
print(data.decode("utf-8")) 补充:
网络 IO模型
2.非阻塞IO模型
协程是一种非阻塞IO
1.setblocking(False)将阻塞修改非阻塞
2.一旦是非阻塞 在执行accept recv send 就会立马尝试读写数据 一旦数据没有准备
好就抛出异常
3.捕获异常
4.如果没有异常说明数据准备好了 直接处理
5.捕获到异常 那就做别的事情
可以实现单线程并发的效果 会大量占用CPU资源 3.多路复用
将所有连接家给select来管理 管什么? 管哪个连接可以被及处理
作为处理任务的乙方事情变少了 不需要重复不断的问操作系拿数据 而是等待select返回需要处
理的连接
等待则意味着select是阻塞的 3.1 创建连接和管理连接
1.创建服务器socket对象
2.将服务器对象交给select来管理
3.一旦有客户端发起连接 select将不在阻塞
4.select将返回一个可读的socket对象(第一次只有服务器)
5.服务器的可读代表有连接请求 需要执行accept 返回一个客户端连接conn 由于是非阻塞 不能立
即去recv
6.把客户端socket对象也交给select来管理 将conn加入两个被检测的列表中
7.下一次检测到可读的socket可能是服务器 也可能是客户端 所以加上判断 服务器就accept 客户端
就revc
8.如果检测到有可写(可以send就是系统缓存可用)的socket对象 则说明可以向客户端发送数据了
7 and 8 的执行顺序是不固定的 3.2 处理数据收发
两个需要捕获异常的地方
1.recv 执行第七步 表示可以读 为什么异常 只有一种可能是客户端断开连接
还需要加上 if not 判断是否有数据 linux下 对方下线不会抛出异常 会收到空消息
2.send 执行第八步 表示可以写 为什么异常 只有一种可能客户端断开连接 异步IO 不仅仅指网络IO 也包括本地IO
非阻塞IO 和多路复用 解决的都是网络IO的阻塞问题
本地IO 可以通过子线程 或子进程 来避免阻塞 但是对子线程或者子进程而言 依旧会阻塞 最终的解决方案就是协程 asyncio 该模块实现异步IO 内部使用协程实现

多路复用 阻塞/非阻塞IO模型 网络IO两个阶段的更多相关文章

  1. IO模型介绍 以及同步异步阻塞非阻塞的区别

      阻塞:用户进程访问数据时,如果未完成IO,等待IO操作完成或者进行系统调用来判断IO是否完成非阻塞:用户进程访问数据时,会马上返回一个状态值,无论是否完成 同步:用户进程发起IO(就绪判断)后,轮 ...

  2. 并发编程 - IO模型 - 1.io模型/2.阻塞io/3.非阻塞io/4.多路复用io

    1.io模型提交任务得方式: 同步:提交完任务,等结果,执行下一个任务 异步:提交完,接着执行,异步 + 回调 异步不等结果,提交完任务,任务执行完后,会自动触发回调函数同步不等于阻塞: 阻塞:遇到i ...

  3. python开发IO模型:阻塞&非阻塞&异步IO&多路复用&selectors

    一 IO模型介绍 为了更好地了解IO模型,我们需要事先回顾下:同步.异步.阻塞.非阻塞 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非 ...

  4. [翻译]各个类型的IO - 阻塞, 非阻塞,多路复用和异步

    同事推荐,感觉写的不错就试着翻译了下. 原文链接: https://www.rubberducking.com/2018/05/the-various-kinds-of-io-blocking-non ...

  5. linux基础编程:IO模型:阻塞/非阻塞/IO复用 同步/异步 Select/Epoll/AIO(转载)

      IO概念 Linux的内核将所有外部设备都可以看做一个文件来操作.那么我们对与外部设备的操作都可以看做对文件进行操作.我们对一个文件的读写,都通过调用内核提供的系统调用:内核给我们返回一个file ...

  6. (转)同步异步,阻塞非阻塞 和nginx的IO模型

    同步异步,阻塞非阻塞 和nginx的IO模型  原文:https://www.cnblogs.com/wxl-dede/p/5134636.html 同步与异步 同步和异步关注的是消息通信机制 (sy ...

  7. Linux IO模型(同步异步阻塞非阻塞等)的几篇好文章

    聊聊同步.异步.阻塞与非阻塞聊聊Linux 五种IO模型聊聊IO多路复用之select.poll.epoll详解 ​

  8. 理解同步,异步,阻塞,非阻塞,多路复用,事件驱动IO

    以下是IO的一个基本过程 先理解一下用户空间和内核空间,系统为了保护内核数据,会将寻址空间分为用户空间和内核空间,32位机器为例,高1G字节作为内核空间,低3G字节作为用户空间.当用户程序读取数据的时 ...

  9. python并发编程之IO模型 同步 异步 阻塞 非阻塞

    IO浅谈 首先 我们在谈及IO模型的时候,就必须要引入一个“操作系统”级别的调度者-系统内核(kernel),而阻塞非阻塞是跟进程/线程严密相关的,而进程/线程又是依赖于操作系统存在的,所以自然不能脱 ...

随机推荐

  1. VBA find查找行号和列号的方法

    ).Worksheets(1).Range("b:b").Find("*", , , , , xlPrevious).Row)'查找最大行号 ).Workshe ...

  2. 借助python工具从word文件中抽取相关表的定义,最后组装建表语句-非常好

    借助python工具从word文件中抽取表的定义,最后组装建表语句-非常好 --如有转载请以超链接的方式注明原文章出处,谢谢大家.请尊重每一位乐于分享的原创者 1.python脚本 ## -*- co ...

  3. cookie VS localstorage

    http://jerryzou.com/posts/cookie-and-web-storage/ cookie: 1. 数据上限4KB左右 2. 一般由服务器生成,可设置失效时间.如果在浏览器端生成 ...

  4. Linux使用ntpdate和ntpd进行时间同步

    生产环境关联主机间常要求时间一致,若有NTP时间同步服务器,可配置各主机与时间同步服务器同步时间. 1.使用ntpdate进行时间同步 安装ntp客户端: yum install ntpdate 同步 ...

  5. Qt动态布局

    QVBoxLayout *m_pvLayout = NULL: QWidget *m_pWidgetPlay = NULL: m_pvLayout = new QVBoxLayout(this); m ...

  6. etymon word air aero aeri aer ag agreement walk joint trick skill chief forget out~1

      1● air 2● aero 3● aeri 4● aer 空气 充气       1● ag     做,代理做   =====>agency       1● agr 2● agri 3 ...

  7. prefix word se sub suc sup suf sur out~s

    1★ se 区分开,分开 ,离开   2★ sub 接近,靠近,次一等 ,次的   3★ suc 4★ sup   5★ suf     6★ sur 在~下面    

  8. python两个字典合并,两个list合并

    1.两个字典:a={'a':1,'b':2,'c':3} b= {'aa':11,'bb':22,'cc':33} 合并1:dict(a,**b)  操作如下: 合并2:dict(a.items()+ ...

  9. 学习笔记-AngularJs (一)

    最近对AngularJs产生了浓厚的学习兴趣,于是便搜罗所有资料,开始学习起来,也希望把学习过程记录下来. 首先学习之前,需要对AngularJs进行个大概的了解: AngularJS[1]  诞生于 ...

  10. 【用例管理】用testng的groups管理用例

    一.需求: 测试时经常有两种场景,第一种是冒烟测试的小部分用例:一类是全部用例. 二.针对第一种运行部分的用例,可以用groups来管理 package com.testcases; import o ...