# django不是一个异步框架
# tornado是异步的web框架
# 处理每秒大量的请求 # 个人理解的IO:就是应用层与内核驱动层的交互,这个过程无论从应用层到内核中,还是驱动层等待硬件层的数据,都是需要时间的,这个过程是IO操作过程 # 五种IO Model
# blocking IO 阻塞IO
# nonblocking 非阻塞IO
# IO multiplexing IO多路复用
# signal driven IO 信号驱动IO
# asynchronous IO 异步IO
# 在python中没有提供异步IO的机制,没有操作系统将数据直接给应用层的获取到数据的接口. 但是由很多python的异步框架
# 这种异步IO机制其实是很好的
# IO发生时涉及的对象和步骤,对于一个network IO,我们以read举例,他会涉及到两个系统对象,一个是调用这个IO的process(or thread),另一个就是系统内核。当一个read操作时,该操作会经历两个阶段
# 1.等待数据准备
# 2.将数据从内核拷贝到应用层

# 同步    提交一个任务之后要等待这个任务执行完毕才能继续执行其他的
# 异步 只管提交任务,不用等待该任务执行完毕就可以继续做其他事情
# 阻塞 运行状态 -> 阻塞状态 -> 就绪状态 -> 运行状态、一进程或线程阻塞则会进入阻塞状态休眠
# 非阻塞

  1.非阻塞IO

# 非阻塞IO
# import socket
# sk = socket.socket()
# sk.setblocking(False) # 设置非阻塞
# sk.bind(('127.0.0.1', 8080))
# sk.listen()
#
# try:
# conn, addr = sk.accept() # 因为将套接字设置为了非阻塞,所以这里会报错,因为accept不允许为非阻塞性的,所以下面捕捉异常,有异常则直接pass
# print('有客户端连接上来 ')
# except BlockingIOError:
# pass

  2.阻塞IO

  3.IO多路复用

    # 在windows、linux上,有一个select专门提供IO多路复用的。
# poll机制 # linux上有
# epoll机制 # linux上有
# poll机制和epoll机制使用方法和select一样
# poll可以监听的对象比select可以监听的多。如果select能监听500,则poll能监听1000个类似这样
# poll和select都是操作系统去轮询机制的监听被监听的项,看是否有读操作等,随着监听列表增多,会导致效率变差
# epoll机制
# 给每一个被监听的对象都绑定了一个回调函数,当被监听的对象有监听事件后,会触发此监听对象绑定的回调函数这种机制比select和poll的轮询效率要高,高并发非常有用
# import selectors 这个模块会帮助你选择当前操作系统上最优的IO多路复用

  3.1 IO多路复用中的select

  服务端

import select   # 内置的select模块,用于IO多路复用
import socket
# select.select(rlist, wlist, xlist, timeout=None)
# 参数是3个列表,一个监听超时时间
# rlist参数,表示监听读,直到监听到读或超时返回
# wlist参数,表示监听写,直到监听到写或超时返回
# xlist参数,表示监听条件
# timeout参数,监听超时时间
# 返回值有三个
sk = socket.socket()
sk.bind(('127.0.0.1', 8080))
sk.setblocking(False) # 设置为非阻塞
sk.listen() read_lst = [sk] # 创建一个列表,想要监听谁,则将哪个对象放进来,这里开始先监听socket对象,当有人向这个socket发起连接的时候,select则会监听到返回一个socket
while 1:
# 调用select后操作系统会帮你监听三个监听列表,这里监听的是监听读列表
r_lst, w_lst, x_lst = select.select(read_lst, [], []) # 当监听到后,返回一个元组,元组中有三个元素,分别是rlist,wlist,xlist。这里rlist中最开始监听sk,因此当有客户端连接上来后,会监听有要被读的事件,这里会返回得到一个r_lst,r_lst中有一个sk对象
#print(r_lst)
for i in r_lst:
if i is sk: # 判断监听到的对象是否是sk对象
conn, addr = i.accept() # 此时直接sk.accpet()就会得到客户端连接和地址
read_lst.append(conn) # 将客户端连接符加入到监听列表中
else: # 如果监听到的不是sk对象, 这里的第二可能是监听到了客户端连接符有要被读的事件
msg = i.recv(1024)
if msg == b'': # 当客户端连接关闭时,会接收到空的数据,
i.close() # 因为客户端连接主动关闭,这里也要关闭下这个客户端连接
read_lst.remove(i) # 同时在监听列表中去除这个客户端连接符,不再去监听它
continue
print(msg)

  3.2 linux上更好的IO多路复用epoll、selectors选择当前系统最优的IO多路复用机制

  服务端

# linux上的selectors IO多路复用机制,IO多路复用机制,默认选择系统最优,linux上肯定选择epoll
import selectors
from socket import * def read(conn, mask):
'''
将来要绑定的回调函数
:param conn:
:param mask:
:return:
'''
try:
data = conn.recv(1024)
if not data: # 如果监听客户端的数据是空数据,则表示客户端连接关闭了
print('closeing', conn)
sel.unregister(conn) # 在监听列表中去除这个客户端连接的监听
conn.close() # 同时服务端也关闭这个客户端连接描述符
return
conn.send(data.upper() + b'SB')
except Exception: # 该客户端连接描述符监听到异常事件,则直接关闭客户端连接
print('closing', conn)
sel.unregister(conn) # 在监听列表中去除这个客户端连接的监听
conn.close() # 同时服务端也关闭这个客户端连接描述符 def accept(server_fileobj, mask):
''' :param server_fileobj: 接收到的socket
:param mask:
:return:
'''
conn, addr = server_fileobj.accpet() # 得到客户端连接描述符
sel.register(conn, selectors.EVENT_READ, read) # 将conn客户端连接符注册到监听列表中,监听的是其读时间,绑定的回调函数是read if __name__ == '__main':
sk = socket()
sk.setblocking(SOL_SOCKET, SO_REUSEPORT, 1)
sk.bind(('127.0.0.1', 8080))
sk.listen(5)
sk.setblocking(False)
sel = selectors.DefaultSelector() # 获取到当前操作系统最优的IO多路复用机制
sel.register(sk, selectors.EVENT_READ, accept) # 将socket对象注册到监听列表中,监听其读事件,当有读事件时绑定的回调函数accpet会被执行 # server_fileobj = socket(AF_INET, SOCK_STREAM)
# server_fileobj.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1)
# server_fileobj.bind(('127.0.0.1', 8080))
# server_fileobj.listen(5)
# server_fileobj.setblocking(False)
# sel.register(server_fileobj, selectors.EVENT_READ, accept) while True:
events = sel.select() # 检测到所有的fileobj(监听列表中的所有对象,都是文件描述符),是否有完成wait data阶段。当监听到有事件时返回
for sel_obj, mask in events:
callback = sel_obj.data # 第一次是callback = accpet 通过sel_obj.data就能拿到刚刚这个被监听对象的回调函数
callback(sel_obj.fileobj, mask) # 第一次是ccpet(server_fileobj, 1) 直接调用回调函数

  客户端

import socket
from threading import Thread def func():
sk = socket.socket()
sk.connect(('127.0.0.1', 8080))
sk.send(b'hello')
sk.close() if __name__ == '__main__':
for i in range(20):
Thread(target=func).start()

  4.信号驱动IO

  5.异步IO

 6.五种IO模型的比较,个人觉得肯定还是异步IO好

说说基于网络的五种IO模型的更多相关文章

  1. 聊聊 Linux 中的五种 IO 模型

    本文转载自: http://mp.weixin.qq.com/s?__biz=MzAxODI5ODMwOA==&mid=2666538919&idx=1&sn=6013c451 ...

  2. Linux 下的五种 IO 模型

    概念说明 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方).操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的 ...

  3. [转载] Linux五种IO模型

      转载:http://blog.csdn.net/jay900323/article/details/18141217     Linux五种IO模型性能分析   目录(?)[-] 概念理解 Lin ...

  4. 2018.5.4 Unix的五种IO模型

    阻塞非阻塞和异步同步 同步和异步关注的是消息通信机制,关注两个对象之间的调用关系. 阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态,关注单一程序. Unix的五种IO模型 以下基于Li ...

  5. Windows五种IO模型性能分析和Linux五种IO模型性能分析

    Windows五种IO模型性能分析和Linux五种IO模型性能分析 http://blog.csdn.net/jay900323/article/details/18141217 http://blo ...

  6. (转载) Linux五种IO模型

    转载:http://blog.csdn.net/jay900323/article/details/18141217     Linux五种IO模型及分析   目录(?)[-] 概念理解 Linux下 ...

  7. 五种IO模型

    参考文档 https://www.jianshu.com/p/486b0965c296 概念说明 用户空间和内核空间        现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空 ...

  8. linux的五种IO模型

    概念: 同步.异步.阻塞.非阻塞的概念 同步:所谓同步,发起一个功能调用的时候,在没有得到结果之前,该调用不返回,也就是必须一件事一件事的做,等前一件做完了,才能做下一件. 提交请求->等待服务 ...

  9. Linux 中的五种 IO 模型

    Linux 中的五种 IO 模型 在正式开始讲Linux IO模型前,比如:同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的.所以先限定一 ...

随机推荐

  1. JavaWeb中的域对象

    域对象:可以在不同Servlet之间传递数据的对象,就是域对象,它们内置了map集合,都有setAttribute和getAttribute方法: Java Web有ServletContext.Se ...

  2. python自测100题

    如果你在寻找python工作,那你的面试可能会涉及Python相关的问题. 通过对网络资料的收集整理,本文列出了100道python的面试题以及答案,你可以根据需求阅读测试.如果你看了还是不懂可以加我 ...

  3. jumpserver部署使用

    一.简介 前面我们聊到了openvpn的部署和使用,它能够实现从互联网通过openvpn连接到公司内网服务器,从而进行远程管理:但openvpn有一个缺点它不能记录哪些用户在内网服务器上操作了什么,拥 ...

  4. 如何在 vue 项目里正确地引用 jquery

    转载 2016年11月13日 使用vue-cli构建的vue项目,webpack的配置文件是分散在很多地方的,而我们需要修改的是build/webpack.base.conf.js,修改两处的代码 / ...

  5. 开发工具:Mybatis.Plus.插件三种方式的逆向工程

    本文源码:GitHub·点这里 || GitEE·点这里 一.逆向工程简介 在Java开发中,持久层最常用的框架就是mybatis,该框架需要编写sql语句,mybatis官方提供逆向工程,可以把数据 ...

  6. DTU是什么 常见的DTU有哪些

    DTU也叫数据传输终端,它的主要功能是把远端设备的数据通过无线的方式传送回后台中心,想要完成数据的传输就需要建立一套完整的数据传输系统.DTU是一种现代物联网行业广泛使用的无线数据终端,利用公用运营商 ...

  7. pandas神器操作excel表格大全(数据分析数据预处理)

    使用pandas库操作excel,csv表格操作大全 关注公众号"轻松学编程"了解更多,文末有公众号二维码,可以扫码关注哦. 前言 准备三份csv表格做演示: 成绩表.csv su ...

  8. PageHelper使用步骤

    一.导入jar包(maven构建导入坐标) <dependency> <groupId>com.github.pagehelper</groupId> <ar ...

  9. Java线程池原理及分析

    线程池是很常用的并发框架,几乎所有需要异步和并发处理任务的程序都可用到线程池. 使用线程池的好处如下: 降低资源消耗:可重复利用已创建的线程池,降低创建和销毁带来的消耗: 提高响应速度:任务到达时,可 ...

  10. Spark集群和任务执行

    [前言:承接<Spark通识>篇] Spark集群组件 Spark是典型的Master/Slave架构,集群主要包括以下4个组件: Driver:Spark框架中的驱动器,运行用户编写Ap ...