python并发编程之IO阻塞基础知识点
IO模型
IO阻塞模型分类:
- 阻塞IO
- 非阻塞IO
- 多路复用IO
- 异步IO(爬虫阶段)
- 信号驱动IO(了解)
1、阻塞IO模型
socket模块默认是阻塞的,一个读操作流程如下:

问题:
同一时间只能服务一个客户端
解决办法:
1. 多线程
优点:如果并发量不高,效率是较高的,因为每个客户端都有单独线程来处理
缺点:不可能无限的开启线程,线程也需要占用资源
2. 多进程
优点:可以多个CPU并行处理
弊端:占用资源非常大,一旦客户端稍微多一点,立马就慢了
3.线程池
优点:保证了服务器正常运行,还帮你负责创建和销毁线程,以及任务分配
缺点:一旦并发量超出最大线程量,就只能等签名的运行完毕。
4. 协程
优点:不需要创建一段线程,也不需要在线程间做切换,没有数量限制
缺点:不能利用多核优势
结果:真正倒是效率低的是阻塞问题,但上述办法并没有真正的解决阻塞问题。
2、非阻塞IO模型
遇到IO操作也不阻塞,会继续执行。意味着即使遇到IO操作CPU执行权也不会被剥夺
从图中看出,非阻塞的recv系统调用之后,进程没有被阻塞,操作系统立马把结果返回给进程,如果数据还没准备好,则抛出异常,进程可以去做其他的事,然后在发起recv系统调用,重复上述过程(这个过程通常被称为轮询),一直到数据准备好,再拷贝数据到进程进行数据处理。需要注意,拷贝数据的整个过程,进程仍然是属于阻塞状态。
缺点: 占用CPU太多,原因是需要无限的循环去向操作系统拿数据。
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', ))
server.listen()
server.setblocking(False)
# 所有客户端的socket
conns = []
# 所有需要返回数据的客户端
send_cs = [] while True:
try:
conn, client_addr = server.accept()
print(client_addr,'已连接')
conns.append(conn)
except BlockingIOError:
# 接收数据
for conn in conns[:]:# 和conns.copy()一样,原因:迭代过程不能删除元素
try:
data = conn.recv()
print(data)
send_cs.append((data, conn))
# send也是IO操作,在一些极端情况下,如系统缓存满了,肯定也会抛出异常
# 所以,send要单拿出来处理
except BlockingIOError:
continue
except ConnectionResetError:
conn.close()
conns.remove(conn)
# 发送数据
for item in send_cs[:]:
data, conn = item
try:
conn.send(data.upper())
# 如果发送成功就把数据从列表中删除
send_cs.remove(item)
except BlockingIOError: # 如果缓冲区满了 就下次再发
continue
except ConnectionResetError:
conn.close()
send_cs.remove(item)
conns.remove(conn)
服务端代码
3、多路复用IO
用一个线程来处理并发所有的客户端。
需要使用select模块,select原理:把所有的socket交给select,select会不断轮询所负责的所有socket,当某个socket有数据到达,就通知进程继续执行后面代码。
流程:程序发起一个select调用,select使整个进程阻塞,直到有socket准备就绪,select就返回,这个时候进程在调用read操作,直接从缓冲中把数据拷贝到进程。流程图如下:

import socket
import select server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("127.0.0.1", ))
server.listen() r_list = [server] # 监测是否收到数据的客户端
w_list = [] # 监测是否需要发送数据的客户端
x_list = [] # 用来发送数据
data_dic = {} while True:
readables, writeables, _ = select.select(r_list, w_list, x_list)
# 接收数据以及建立连接
for conn in readables:
if conn == server:
new_conn, _ = conn.accept()
r_list.append(new_conn)
else:
try:
data = conn.recv()
if not data:
conn.close()
r_list.remove(conn)
continue
print(data)
# 发送数据
w_list.append(conn)
data_dic[conn] = data
except ConnectionResetError:
conn.close()
r_list.remove(conn)
# 发送数据
for conn in writeables:
try:
conn.send(data_dic[conn].upper())
except ConnectionResetError:
conn.close()
finally:
data_dic.pop(conn)
w_list.remove(conn)
服务端代码
import socket
import threading
from threading import Thread def communication():
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', ))
while True:
msg = "%s say hello for you"%threading.current_thread()
if not msg:
continue
client.send(msg.encode("utf-8"))
data = client.recv()
print(data.decode("utf-8")) for i in range():
Thread(target=communication).start()
客户端代码
强调:select的优势在于可以处理多个连接,并不适用于单个连接
优点:占用资源少,不消耗太多CPU,同时能够为多个客户端提供服务。(适用于简单的事件驱动服务器)
缺点:需要消耗大量时间区轮询各个socket,更好的选择时epoll,其次把事件探测和响应夹杂在一起,耦合性增加
python并发编程之IO阻塞基础知识点的更多相关文章
- Python并发编程之IO模型
目录 IO模型介绍 阻塞IO(blocking IO) 非阻塞IO(non-blocking IO) IO多路复用 异步IO IO模型比较分析 selectors模块 一.IO模型介绍 Stevens ...
- python并发编程之IO模型,
了解新知识之前需要知道的一些知识 同步(synchronous):一个进程在执行某个任务时,另外一个进程必须等待其执行完毕,才能继续执行 #所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调 ...
- python并发编程之IO模型(Day38)
一.IO模型介绍 为了更好的学习IO模型,可以先看同步,异步,阻塞,非阻塞 http://www.cnblogs.com/linhaifeng/articles/7430066.html#_label ...
- 33 python 并发编程之IO模型
一 IO模型介绍 为了更好地了解IO模型,我们需要事先回顾下:同步.异步.阻塞.非阻塞 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非 ...
- 五 python并发编程之IO模型
一 IO模型介绍 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问 ...
- python并发编程之IO模型(实践篇)
一.阻塞IO 介绍略(请看概念篇) 二.非阻塞IO 在非阻塞式IO中,用户进程需要不断的主动询问kernel数据准备好了没有 # 服务端 import socket import time serve ...
- 第十篇.6、python并发编程之IO模型
一 IO模型介绍 为了更好地了解IO模型,我们需要事先回顾下:同步.异步.阻塞.非阻塞 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非 ...
- 第 13 章 python并发编程之io模型
一.IO模型介绍 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问 ...
- 38、python并发编程之IO模型
目录: 一 IO模型介绍 二 阻塞IO(blocking IO) 三 非阻塞IO(non-blocking IO) 四 多路复用IO(IO multiplexing) 五 异步IO(Asynchron ...
随机推荐
- WPF 水印TextBox WatermarkTextBox
//https://blog.csdn.net/puchitomato/article/details/12248691 转自以上链接,自己添加了Enter响应事件. public class ...
- 通过Hutool 调用远程API接口(POST/GET)
背景:需要调用第三方接口,开启某项任务,用Hutool代替了HttpClient 调用第三方接口,简单粗暴. 代码如下: import java.util.Date; import org.apach ...
- Gerrit系统框架介绍
Gerrit目录介绍 转自:https://blog.csdn.net/tanshizhen119/article/details/79889242 先上图 bin/ : 主要是放gerrit.sh启 ...
- Play vue.js with constant value in SailsJS
SailsJS supplies a utility module called parasails, which defines two elements, <ajax-form> an ...
- OpenGL Windows 窗口程序环境搭建
OpenGL环境搭建步骤: Downloading OpenGL 根据官网的说法: In all three major desktop platforms (Linux, macOS, and Wi ...
- 教你一步永久激活WebStorm2018
工欲善其事必先利其器,我们在开发过程中,编辑器是我们提高开发效率及生产必备的工具,如何发现一个高效好用的编辑器是程序员必备的技能之一. 前端开发有众多编辑器 sublime.vscode.webstr ...
- DVWA-XSS学习笔记
DVWA-XSS XSS概念:由于web应用程序对用户的输入过滤不严,通过html注入篡改网页,插入恶意脚本,从而在用户浏览网页时,控制用户浏览器的一种攻击. XSS类型: 反射型XSS:只是简单地把 ...
- Cordova入门系列(一)创建项目 转发 https://www.cnblogs.com/lishuxue/p/6008678.html
版权声明:本文为博主原创文章,转载请注明出处 Cordova是什么? 初学Cordova的人,虽然了解一点点,知道Cordova是用来将html, css, js变成app的,但并不知道到底是怎么用的 ...
- batch 常用命令
1 echo 和 @ 回显命令 @ # 关闭单行回显 echo off # 从下一行开始关闭回显 @echo off # 从本行开始关闭回显,一般批处理第一行都是这个 echo on # 从下一行开始 ...
- IdentityServer4实战 - 与API单项目整合
一.前言 我们在实际使用 IdentityServer4 的时候,可能会在使用 IdentityServer4 项目添加一些API,比如 找回密码.用户注册.修改用户资料等,这些API与Identit ...