python 并发编程 阻塞IO模型
阻塞IO(blocking IO)
在linux中,默认情况下所有的socket都是blocking,一个典型的读操作流程大概是这样:

当用户进程调用了recvfrom这个系统调用,kernel内核就开始了IO的第一个阶段:准备数据。对于network io( 网络io )来说,很多时候数据在一开始还没有到达(比如,还没有收到一个完整的UDP包),这个时候kernel( 内核 )就要等待足够的数据到来。
等着对方把数据放到自己操作系统内存
而在用户进程这边,整个进程会被阻塞。当kernel一直等到数据准备好了,它就会将数据从kernel操作系统缓存中拷贝到用户应用程序内存,
然后kernel返回结果,用户进程才解除block的状态,重新运行起来。
这就是阻塞IO
所以,blocking IO的特点就是在IO执行的两个阶段(等待数据和拷贝数据两个阶段)都被block了
网络编程都是从listen\(\)、send\(\)、recv\(\) 等接口开始的,
使用这些接口可以很方便的构建服务器/客户机的模型。然而大部分的socket接口都是阻塞型的。如下图 ps:
所谓阻塞型接口是指系统调用(一般是IO接口)不返回调用结果并让当前线程一直阻塞
只有当该系统调用获得结果或者超时出错时才返回。
服务端:
from socket import * server = socket(AF_INET,SOCK_STREAM)
server.bind(('127.0.0.1',8000))
server.listen(5) while True:
print("starting...")
conn,addr = server.accept()
print(addr) while True:
try:
data = conn.recv(1024)
if not data:break
conn.send(data.upper()) except ConnectionResetError:
break server.close()
客户端
from socket import * client = socket(AF_INET,SOCK_STREAM)
client.connect(('127.0.0.1',8000)) while True:
msg = input(">>>:").strip()
if not msg:continue
client.send(msg.encode("utf-8"))
data = client.recv(1024)
print(data.decode("utf-8")) client.close()

实际上,除非特别指定,几乎所有的IO接口 ( 包括socket接口 ) 都是阻塞型的。这给网络编程带来了一个很大的问题,如在调用recv(1024)的同时,线程将被阻塞,在此期间,线程将无法执行任何运算或响应任何的网络请求。
一个简单的解决方案:
在服务器端使用多线程(或多进程)。多线程(或多进程)的目的是让每个连接都拥有独立的线程(或进程),
这样任何一个连接的阻塞都不会影响其他的连接。
该方案的问题是 :
开启多进程或都线程的方式,在遇到要同时响应成百上千路的连接请求,则无论多线程还是多进程都会严重占据系统资源,
降低系统对外界响应效率,而且线程与进程本身也更容易进入假死状态。
随着客户端数量增多,无限制的开线程,开销非常大
不能解决阻塞IO问题 ,解决思路:起多线程
改进方案:
使用“线程池”或“连接池”。“线程池”旨在减少创建和销毁线程的频率,
其维持一定合理数量的线程,并让空闲的线程重新承担新的执行任务。“连接池”维持连接的缓存池,尽量重用已有的连接、
减少创建和关闭连接的频率。这两种技术都可以很好的降低系统开销,都被广泛应用很多大型系统,如websphere、tomcat和各种数据库等。
改进后方案其实也存在着问题:
“线程池”和“连接池”技术也只是在一定程度上缓解了频繁调用IO接口带来的资源占用。而且,所谓“池”始终是有限,
当请求大大超过上限时,“池”构成的系统对外界的响应并不比没有池的时候效果好多少。所以使用“池”必须考虑其面临的响应规模,
并根据响应规模调整“池”的大小。
线程池应该随着规模数调大,但是调大线程池,要在机器可承受范围之内。不能把线程池无限调大,这样相当于无限开线程一样,
多线程还是要用在规模比较小的情况
对应上例中的所面临的可能同时出现的上千甚至上万次的客户端请求,“线程池”或“连接池”或许可以缓解部分压力,但是不能解决所有问题。总之,多线程模型可以方便高效的解决小规模的服务请求,但面对大规模的服务请求,多线程模型也会遇到瓶颈,可以用非阻塞接口来尝试解决这个问题。
总结:
始综没有解决单线程遇到IO问题,单线程遇到IO,就阻塞,用的是阻塞IO模型。
阻塞IO模型就是遇到IO阻塞不处理,就在原地等着。
应该:
监测单线程IO,遇到IO了,这个线程不要阻塞。直接切换到另外一个线程运行,这样单线程效率就非常高了。
要解决的问题是:
单线程IO问题
python 并发编程 阻塞IO模型的更多相关文章
- python 并发编程 多路复用IO模型
多路复用IO(IO multiplexing) 这种IO方式为事件驱动IO(event driven IO). 我们都知道,select/epoll的好处就在于单个进程process就可以同时处理多个 ...
- python 并发编程 异步IO模型
异步IO(Asynchronous I/O) Linux下的asynchronous IO其实用得不多,从内核2.6版本才开始引入.先看一下它的流程: 用户进程发起read操作之后,立刻就可以开始去做 ...
- Python之网络编程之并发编程的IO模型,
了解新知识之前需要知道的一些知识 同步(synchronous):一个进程在执行某个任务时,另外一个进程必须等待其执行完毕,才能继续执行 #所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调 ...
- python网络编程——网络IO模型
1 网络IO模型介绍 服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种: (1)同步阻塞IO(Blocking IO):即传统的IO模型. (2)同步非阻塞IO(Non-bl ...
- Python并发编程之IO模型
目录 IO模型介绍 阻塞IO(blocking IO) 非阻塞IO(non-blocking IO) IO多路复用 异步IO IO模型比较分析 selectors模块 一.IO模型介绍 Stevens ...
- python并发编程之IO模型,
了解新知识之前需要知道的一些知识 同步(synchronous):一个进程在执行某个任务时,另外一个进程必须等待其执行完毕,才能继续执行 #所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调 ...
- 【并发编程】IO模型
一.要点回顾 为了更好地了解IO模型,我们需要先回顾下几个概念:同步.异步.阻塞.非阻塞 同步: 一个进程在执行某个任务时,另外一个进程必须等待其执行完毕,才能继续执行.就是在发出一个功能调用时,在没 ...
- 33 python 并发编程之IO模型
一 IO模型介绍 为了更好地了解IO模型,我们需要事先回顾下:同步.异步.阻塞.非阻塞 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非 ...
- 五 python并发编程之IO模型
一 IO模型介绍 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问 ...
随机推荐
- Acwing-116-飞行员兄弟(二进制枚举)
链接: https://www.acwing.com/problem/content/description/118/ 题意: "飞行员兄弟"这个游戏,需要玩家顺利的打开一个拥有1 ...
- win10 去掉资源管理器左侧的Creative Cloud Files
open regedit 依次打开HKEY_CLASSES_ROOT\CLSID\{0E270DAA-1BE6-48F2-AC49-95A54E35F3C4} 双击{0E270DAA-1BE6-48F ...
- 10、堆叠窗口StackedWidget
新建项目,基类选择QMainWindow,勾选ui 堆叠窗口有三个page,每个page有个label button处,快捷菜单,转到槽,添加代码 void MainWindow::on_push ...
- textstudio添加中文支持
修改编译器为XeLaTeX,方法如下: Options -> Configure -> Build -> Default Compiler -> XeLaTeX 并在文本开头处 ...
- Android 造炫目的圆形菜单 秒秒钟高仿建行圆形菜单
1.概述 今天打开建行看存款,一看伤心欲绝,再看:我擦,这个圆形菜单挺炫.于是,为了掩盖我悲痛的心情,我决定是实现这个效果.好了,其实还有个原因,记得我初学android那会我做的应用被鄙视了,说我的 ...
- [LOJ3109][TJOI2019]甲苯先生的线段树:DP
分析 首先,请允许我 orz HN队长zsy.链接 我们发现树上的链有两种类,一类是直上直下的,一类不是直上直下的(废话).并且,如果我们确定了左侧和右侧的链的长度和整条链上所有节点的编号之和,那么这 ...
- AcWing:106. 动态中位数(对顶堆)
依次读入一个整数序列,每当已经读入的整数个数为奇数时,输出已读入的整数构成的序列的中位数. 输入格式 第一行输入一个整数PP,代表后面数据集的个数,接下来若干行输入各个数据集. 每个数据集的第一行首先 ...
- OPTS参数设置
今天再hive on tez 跑任务的时候 OOM异常 然后找了些 JAVA OPTS设置: AVA_OPTS ,顾名思义,是用来设置JVM相关运行参数的变量. JVM:JAVA_OPTS=" ...
- [BZOJ2286][Sdoi2011]消耗战(虚树上DP)
2286: [Sdoi2011]消耗战 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6457 Solved: 2533[Submit][Statu ...
- 前端MVC、MVVM的简单实现
MVC MVC是一种设计模式,它将应用划分为3个部分:数据(模型).展示层(视图)和用户交互层.结合一下下图,更能理解三者之间的关系.换句话说,一个事件的发生是这样的过程 用户和应用交互 控制器的事件 ...