Python IO模型
这篇博客是本人借鉴一些大神的博客并结合自己的学习过程写下的。
事件驱动模型
事件驱动模型是一种编程范式,这里程序的执行流由外部事件来决定。它的特点是包含一个事件循环,当外部事件发生时,不断从队列里取出事件,根据不同的事件,调用不同的函数,然后通过使用回调机制来触发相应的处理。
IO多路复用
阻塞IO(blocking IO)
当用户进程调用了recvfrom时,kernel就开始准备数据。在此期间对于network io来说,很多时候完整的数据在一开始还没有到达,这个时候kernel就要等待足够的数据到来。而在Process这边,整个进程便会被阻塞。当kernel一直等到数据准备好了,它就会将数据从kernel中拷贝到用户内存,然后kernel返回结果,用户进程才解除block的状态,重新运行起来。
非阻塞IO(non-blocking IO)
当用户进程向kernel发送数据请求时,如果数据还没有到kernel中,那么就会返回一个error。当用户进程收到error后,会不断地向kernel发送数据请求,直到最后拿到数据。在每一次recvfrom的时候,CPU的权限还在进程这里,那么CPU便可以干点其他事情。但是需要注意,拷贝数据整个过程,进程仍然是属于阻塞的状态。
IO多路复用(IO multiplexing)
select就是一种IO multiplexing,当用户进程调用了select,那么整个进程会被block,而同时,kernel会“监视”所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。这个时候用户进程再调用read操作,将数据从kernel拷贝到用户进程。IO multiplexing的优点在于能够同时处理多个connection,另外process的阻塞是被select这个函数block,而不是被socket IO给block。
异步IO(Asynchronous IO)
用户进程发起read操作之后,立刻就可以开始去做其它的事。而另一方面,从kernel的角度,当它受到一个asynchronous read之后,首先它会立刻返回,所以不会对用户进程产生任何block。然后,kernel会等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,kernel会给用户进程发送一个signal,告诉它read操作完成了。
select模块实例
##############server##############
import socket, select
sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sk.bind(("192.168.43.159", 8001))
sk.listen(5)
inputs = [sk,]
while True:
r,w,e = select.select(inputs, [], [], 5) ##监听
for obj in r:
if obj == sk:
conn,addr = obj.accept()
print(conn)
inputs.append(conn)
else:
try:
data = obj.recv(1024)
print(data.decode("UTF-8"))
inp = input("回答%s号客户:" %inputs.index(obj))
obj.sendall(inp.encode("utf-8"))
except Exception: ##防止连接断开
inputs.remove(obj) ##############client##############
import socket
sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sk.connect_ex(("192.168.43.159", 8001))
while True:
answ = input(">>>")
sk.send(answ.encode("utf8"))
data = sk.recv(1024)
print(data.decode("utf-8"))
最新文章
- NDK开发_笔记0
- Java(异常处理)动手动脑
- github for windows 安装失败解决方案(亲测)
- 【资料分享】 OpenCV精华收藏
- Android Timer的使用
- ZOJ 3511 不相交切切多边形 线段树求最大边数
- sqlserver查询编辑器编辑数据
- Ubuntu16.04安装NVIDIA驱动时的一些坑与解决方案
- C#设计模式之五创建者模式(Builder)【创建型】
- python 小白(无编程基础,无计算机基础)的开发之路 day2
- warning: a non-numeric value encountered in line *的解决方法
- ES6新增的数据类型Map和Set。
- 使用命令行执行jmeter的方法
- LOJ2014 SCOI2016 萌萌哒 并查集、ST表优化连边
- Trickbot增加的远程应用程序凭证抓取功能
- veri HDL modeisim仿真:test bench文件编写
- Java语法基础学习DayNine(Java集合)
- Redis和Memcache的区别总结-京东阿里面试
- Error : The specified component was not reported by the VSS writer (Error 517) in Windows Server 2012 Backup
- kindle paperwhite3 连不上WIFI解决方法
热门文章
- Lua无法排序的问题(Key需要是连续的)
- python3中list列表的一些操作
- IntelliJ IDEA LicenseServer激活及使用
- Docker容器资源管理
- D. Diverse Garland Codeforces Round #535 (Div. 3) 暴力枚举+贪心
- MySQL高级知识(三)——索引
- Java面试知识点之计算机网络篇(一)
- 5.02-requests_proxy
- redis 查找附近的人
- Python中使用class(),面向对象有什么优势 转自知乎