Python_阻塞IO、非阻塞IO、IO多路复用
0、承上
进程:
计算机里最小的资源分配单位;
数据隔离, 利用多核,数据不安全。
线程:
计算机中最小的CPU调度单位;
数据共享,GIL锁,数据不安全.
协程:
线程的一部分,是有用户来调度的;
数据共享,数据安全.
异步: 同时做不止一件事情.
同步: 事情一件接着一件 的做.
阻塞: recv、recvfrom、accept、sleep、input
非阻塞:平时遇见的处过上边基本上都是。
IO操作:
网络相关的操作
文件处理、json.dump/load、logging、print、input、recv/send、connect/accept、recvfrom/sendto
recv为什么要阻塞?
等待数据到来到Python程序的内存中。
IO模型一共有五种,由于信号驱动IO不常用,我们这里主要介绍阻塞IO、非阻塞IO、IO多路复用以及异步IO。
对于一个network IO(这里以read举例),它会涉及到两个系统对象,一个是调用这个IO的process(or thread),另一个就是系统内核(kernel).当一个read操作发生时,该操作会经历两个阶段:
(1) 等待数据准备( Waiting for the data to be ready )
(2) 将数据从内核拷贝到进程中( Copying the data from the kernel to the process )
这些IO模型的区别就在这两个阶段上各有不同.
1、阻塞IO( Blocking IO )
在Linux中,默认情况下所有的socket都是blocking读操作流程大概如下:
- import socket
- sk = socket.socket()
- sk.setblocking(True)
- # True 阻塞
- # False 非阻塞
- # TCP协议的socket sever不能同时接收多个请求
- # sk.accept()
- # while True:
- # conn.recv()
2、非阻塞IO(non-blocking IO)
非阻塞的形式实现了并发的socket server.
非阻塞的形式实现了并发的socket sever,太耗CPU.
没有数据来的时候程序的高速处理极大地占用了CPU资源.
- import socket
- sk = socket.socket()
- sk.bind(('127.0.0.1', 9000))
- sk.setblocking(False)
- sk.listen()
- conn_lst = []
- del_lst = []
- while True:
- try:
- conn,addr = sk.accept() # 非阻塞,没有连接来就报错
- conn_lst.append(conn)
- print(conn)
- except BlockingIOError:
- for con in conn_lst:
- try:
- con.send(b'hello')
- try:
- print(con.recv(1024)) # 非阻塞 没有消息来就报错
- except BlockingIOError: # 没有消息就报错
- pass
- except ConnectionResetError: # send没有连接的报错
- con.close()
- del_lst.append(con)
- for con in del_lst:
- conn_lst.remove(con)
- del_lst.clear()
服务器端
- import socket
- sk = socket.socket()
- sk.connect(('127.0.0.1', 9000))
- while True:
- print(sk.recv(1024))
- sk.send(b'bye')
- sk.close()
客户端
sever:
结果:
- D:\Python36\python.exe E:/Python/草稿纸0.py
- <socket.socket fd=268, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000), raddr=('127.0.0.1', 51839)>
- b'bye'
- b'byebye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- b'byebye'
- b'bye'
- b'bye'
- b'bye'
- b'byebye'
- b'bye'
- b'bye'
- b'bye'
- b'bye'
- Process finished with exit code 1
服务器端
- D:\Python36\python.exe E:/Python/草稿纸.py
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hello'
- b'hellohellohello'
- b'hello'
- b'hello'
- b'hellohellohello'
- b'hello'
- b'hello'
- b'hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello'
- b'hellohello'
- b'hello'
客户端结果
由于通信的一直是小数据块(大小不够1024),出现了黏包现象.
3、IO多路复用(IO multiplexing)
- import select
- import socket
- sk = socket.socket()
- sk.bind(('127.0.0.1', 9000))
- sk.setblocking(False)
- sk.listen()
- rlst = [sk] # 监听的是对象的读操作
- wlst = [] # 监听的是对象的写操作
- xlst = [] # 监听的是对象的异常操作
- while True:
- rl,wl,xl = select.select(rlst, wlst, xlst)
- for obj in rl:
- if obj == sk:
- conn,addr = sk.accept()
- rlst.append(conn)
- else:
- msg = obj.recv(1024)
- if msg == b'':
- obj.close()
- rlst.remove(obj)
- continue
- print(msg)
- obj.send(b'hello')
IO多路复用-sever端
- import socket
- sk = socket.socket()
- sk.connect(('127.0.0.1', 9000))
- while True:
- sk.send(b'wahaha')
- print(sk.recv(1024))
- sk.close()
IO多路复用-client端
socketsever —— TCP协议的并发操作 selectors + 多线程
IO多路复用的select的工作机制
select Windows 轮询
poll Linux 轮询,poll能够监听的对象比select要多
epoll Linux 不是采用轮询的方式,而是采用回调函数的形式
Python_阻塞IO、非阻塞IO、IO多路复用的更多相关文章
- IO多路复用,同步,异步,阻塞和非阻塞 区别
一.什么是socket?什么是I/O操作? 我们都知道unix(like)世界里,一切皆文件,而文件是什么呢?文件就是一串二进制流而已,不管socket,还是FIFO.管道.终端,对我们来说,一切都是 ...
- IO多路复用,同步,异步,阻塞和非阻塞 区别(转)
转自:http://www.cnblogs.com/aspirant/p/6877350.html?utm_source=itdadao&utm_medium=referral 同步.异步 是 ...
- IO模型--阻塞IO,非阻塞IO,IO多路复用,异步IO
IO模型介绍: * blocking IO 阻塞IO * nonblocking IO 非阻塞IO * IO multiplexing IO多路复用 * signal driven IO 信号驱动IO ...
- Python网络编程-IO阻塞与非阻塞及多路复用
前言 问题:普通套接字实现的服务端的缺陷 一次只能服务一个客户端! accept阻塞! 在没有新的套接字来之前,不能处理已经建立连接的套接字的请求 re ...
- python 全栈开发,Day44(IO模型介绍,阻塞IO,非阻塞IO,多路复用IO,异步IO,IO模型比较分析,selectors模块,垃圾回收机制)
昨日内容回顾 协程实际上是一个线程,执行了多个任务,遇到IO就切换 切换,可以使用yield,greenlet 遇到IO gevent: 检测到IO,能够使用greenlet实现自动切换,规避了IO阻 ...
- {python之IO多路复用} IO模型介绍 阻塞IO(blocking IO) 非阻塞IO(non-blocking IO) 多路复用IO(IO multiplexing) 异步IO(Asynchronous I/O) IO模型比较分析 selectors模块
python之IO多路复用 阅读目录 一 IO模型介绍 二 阻塞IO(blocking IO) 三 非阻塞IO(non-blocking IO) 四 多路复用IO(IO multiplexing) 五 ...
- 同步和异步 阻塞和非阻塞 IO多路复用和select总结
同步和异步的概念 同步是指用户线程发起IO请求后,需要等待或者轮询内核IO操作完成后才能继续执行: 异步是指用户线程发起IO请求后仍继续执行,当内核IO操作完成后会通知用户线程或者调用用户线程注册的回 ...
- (IO模型介绍,阻塞IO,非阻塞IO,多路复用IO,异步IO,IO模型比较分析,selectors模块,垃圾回收机制)
参考博客: https://www.cnblogs.com/xiao987334176/p/9056511.html 内容回顾 协程实际上是一个线程,执行了多个任务,遇到IO就切换 切换,可以使用yi ...
- IO阻塞模型、IO非阻塞模型、多路复用IO模型
IO操作主要包括两类: 本地IO 网络IO 本地IO:本地IO是指本地的文件读取等操作,本地IO的优化主要是在操作系统中进行,我们对于本地IO的优化作用十分有限 网络IO:网络IO指的是在进行网络操作 ...
- 网络IO之阻塞、非阻塞、同步、异步总结
网络IO之阻塞.非阻塞.同步.异步总结 1.前言 在网络编程中,阻塞.非阻塞.同步.异步经常被提到.unix网络编程第一卷第六章专门讨论五种不同的IO模型,Stevens讲的非常详细,我记得去年看第一 ...
随机推荐
- 虚机抓取Hyper-V宿主的镜像流量(Windows Server 2012R2)
1.将交换机流量镜像到Hyper-V宿主的一块网卡(eth4) 2.在Hyper-V宿主上新建虚拟交换机(Network_Mirror),选择外部网络,扩展属性中启用“Microsoft NDIS捕获 ...
- docker往阿里云推镜像和打包镜像
向仓库推镜像 1. 登录到阿里云docker镜像站点,然后创建仓库. 2.要按照阿里云官方给定的仓库名称来使用,所以我们一般都要继续给准备要上传的镜像二次添加标签,如下所示: 3.在终端登录阿里云站点 ...
- Glyphicons 字体图标
- Unix/Linux环境C编程新手教程(21) 各个系统HelloWorld跑起来效果怎样?
版权声明:本文为博主尹成联系QQ77025077,微信18510341407原创文章,欢迎转载侵权不究. https://blog.csdn.net/yincheng01/article/detail ...
- json_encode里面经常用到的 JSON_UNESCAPED_UNICODE和JSON_UNESCAPED_SLASHES
php格式化json的函数json_encode($value,$options) 其中有2个比较常用到的参数 JSON_UNESCAPED_UNICODE(中文不转为unicode ,对应的数字 2 ...
- 【vue】饿了么项目的相关笔记链接
http://www.mtons.com/content/1819.htm http://www.tuicool.com/articles/F7BnaiY https://segmentfault.c ...
- Redis之过期时间
1.命令介绍 expire key seconds 设置key的有效时间,单位为秒expire命令返回1表示设置成功,返回0表示键不存在或设置失败. ttl keyttl命令返回值是键的剩余时间 ...
- SpringBoot之静态资源放行
为了提高开发效率,编写对应的代码生成器.代码生成器主要有两个方面,一个是在线Web,另外一个是运行某个类. 使用的技术是SpringBoot+MyBatis-Plus+MySQL+JDK8. 在编写在 ...
- 简单使用普通用户启动tomcat
新建用户tomcat,该用户不能登录 useradd tomcat -s '/sbin/nologin' 将/usr/local/tomcat/bin/startup.sh更名 mv /usr/loc ...
- nginx指定配置文件启动
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf