并发编程---IO模型
2020-02-01 00:59
627 查看
IO模型
任务的提交方式有两种:
- 同步:应用程序提交完任务,等待结果结果,之后在执行下一个任务
- 异步:应用程序提交完任务,继续执行不等待结果,任务执行完,会自动出发异步中的会带哦函数
同步不等于阻塞:
- 同步:提交任务完,不管任务有没有遇到阻塞,只等待接收结果,任务运行完,才接着往下走
- 阻塞:提交任务的时候遇到IO,没有处理的话,操作系统就会抢走CPU。解决方法:使用gevent,检测到IO的时候,就切换到其他任务
IO模型的主要分类:
- 阻塞IO blocking IO
- 非阻塞IO nonblocking IO
- IO多路复用 IO multiplexing
- 信号驱动IO signal driven IO
- 异步IO asynchronous IO
遇到IO会阻塞:卡在原地; 网络IO:原地阻塞
1.server端什么样得操作属于IO行为
- 服务端的accept,recv,send,
- 其中accept,recv会感觉明显的等,
- send 不会明显等,但也是IO行为
2.为什么IO行为会让有在原地等待的效果
由于server在recv的时候 会有一个等待的时间,就是等待操作系统缓存中存在数据,才copy到用程序当中
阻塞IO
import socket from threading import Thread server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) server.bind(('127.0.0.1',8080)) server.listen(5) def communicate(): while True: try: data = conn.recv(1024) print('接收的数据:' ,data) conn.send(data.upper()) except ConnectionResetError: break conn.close() print('setting...') while True: print('settings') conn,client_addr = server.accept() # io阻塞,操作系统拿走了cpu print(client_addr) t = Thread(target=communicate,args=(conn,)) t.start() server.close()服务端
import socket client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) client.connect(('127.0.0.1',8080)) while True: cmd = input('>>:').strip() if not cmd:continue client.send(cmd.encode('utf-8')) data = client.recv(1024) print(data) phone.close()客户端
非阻塞IO
应用程序自己检测io,遇到io就切给其他的任务,这样可以使单线程的效率大大提高
存在的问题:
- cpu在做其他的事情时候,传来了数据,不会立即响应
- 服务端没有任何的阻塞,就是死循环,cpu会一直的运转,进程处于就绪状态,这样大量占用cpu,让应用程序一直向操作系统询问数据好没好,在做着无用功
多路复用IO
阻塞io: 有wait()等待过程,copy过程,
多路复用io: 比阻塞io多了一个select过程,这个过程可以作为中介,询问操作系统有没有数据
- 缺点:只有一个套接字的时候比阻塞io性能低,当监测多个套接字的时候,循环慢,列表数据多的话,效率低
- 优点:多个套接字的时候,可以交给select处理,比阻塞io性能高
elect :列表循环 效率低
poll :可接收得列表数据多 效率也不高
epoll :效率最高,通过异步操作 每个套接字身上绑定个回调函数,谁好了谁触发回调,(就不用去遍历了 效率低)
epoll: windows 没有 ;linux 有
selectors: 模块 自动根据操作系统选择
import socket import select server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) server.bind(('127.0.0.1',8080)) server.listen(5) server.setblocking(False) print('settings') rlist=[server,] #存收的套接字,有两种:conn ,server wlist=[] #存发的套接字 wdata={} while True: rl,wl,xl = select.select(rlist,wlist,[],0.5) #去向操作系统问套接字准备好没有,异常列表[] m每隔0.5秒问一次 print('rl',rl) print('wl',wl) for sock in rl: if sock == server: conn,addr = sock.accept() rlist.append(conn) else: try: #适用于windows系统 data = sock.recv(1024) if not data: #适用于linux系统,会一直收空 sock.close() rlist.remove(sock) continue wlist.append(sock) wdata[sock] = data.upper() except Exception: #客户端连接关闭后走这个异常 sock.close() rlist.remove(sock) for sock in wl: data = wdata[sock] sock.send(data) wlist.remove(sock) #传完数据,就不用监测 wdata.pop(sock) server.close()服务端
import socket client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) client.connect(('127.0.0.1',8080)) while True: cmd = input('>>:').strip() if not cmd:continue client.send(cmd.encode('utf-8')) data = client.recv(1024) print(data.decode('utf-8')) phone.close()客户端
转载于:https://www.cnblogs.com/Mryang123/p/8948098.html
- 点赞
- 收藏
- 分享
- 文章举报
相关文章推荐
- python 并发编程 阻塞IO模型原理解析
- 并发编程 - io模型 - 总结
- 网络编程与并发-IO模型
- Linux网络编程服务器模型选择之IO复用循环并发服务器
- 服务器编程模型 循环服务器->IO复用循环服务器 并发服务器->高性能并发服务器
- python 并发编程 多路复用IO模型详解
- python并发编程:IO模型基础
- python并发编程:IO模型
- python并发编程之IO模型
- 并发编程之IO模型
- python并发编程之IO模型,
- IO复用、多进程和多线程三种并发编程模型比较
- IO复用、多进程和多线程三种并发编程模型
- IO复用、多进程和多线程三种并发编程模型
- 并发编程-IO模型
- Linux网络编程服务器模型选择之IO复用循环并发服务器
- python并发编程之IO模型
- python 并发编程 非阻塞IO模型原理解析
- IO复用、多进程和多线程三种并发编程模型
- 并发编程 - IO模型 - 1.io模型/2.阻塞io/3.非阻塞io/4.多路复用io