1.io 模型
提交任务得方式:
同步: 提交完任务, 等结果, 执行下一个任务
异步: 提交完, 接着执行, 异步 + 回调 异步不等结果, 提交完任务, 任务执行完后, 会自动触发回调函数
同步不等于阻塞:
阻塞: 遇到 io, 自己不处理, os 会抢走 cpu , 解决办法: 监测到 io,gevent 切换到其他任务, 类似欺骗 os
非阻塞: cpu 运行
IO 分类:
1. 阻塞 IO blocking IO
2. 非阻塞 IO nonblocking IO
3.IO 多路复用 IO multiplexing
4. 信号驱动 IO signal driven IO 用得比较少
5. 异步 IO asynchronous IO
遇到 IO: 卡
网络 IO: 原地阻塞
1.server 端什么样得操作属于 IO 行为
# accept recv send 阻塞操作 accept recv 明显得等 send 不会明显等, 但是一种 io 行为
2. 为什么 IO 行为会让有在原地等待的效果
2. 阻塞 io
- server:
- from socket import *
- from threading import Thread
- def communicate(conn):
- while True:
- try:
- data = conn.recv(1024)
- if not data: break
- conn.send(data.upper())
- except ConnectionResetError:
- break
- conn.close()
- server = socket(AF_INET, SOCK_STREAM)
- server.bind(('127.0.0.1',8080))
- server.listen(5)
- while True:
- print('starting...')
- conn, addr = server.accept() # io 阻塞 os 拿走了 cpu
- print(addr)
- t=Thread(target=communicate,args=(conn,))
- t.start()
- server.close()
- client:
- from socket import *
- client=socket(AF_INET,SOCK_STREAM)
- client.connect(('127.0.0.1',8080))
- while True:
- msg=input('>>:').strip()
- if not msg:continue
- client.send(msg.encode('utf-8'))
- data=client.recv(1024)
- print(data.decode('utf-8'))
- client.close()
3. 非阻塞 io:
自己监测 io 遇到 io 就切 并且把 单线程得效率提到最高
导致得问题:
1. 当有数据来得时候, cpu 在做其他得事情, 不会立即响应
2. 服务端没有任何阻塞, 说白了, 就是死循环, cpu 会一直运转, 线程处于就绪状态, 大量占用 cpu , 做无用, 这个线程会一直问 cpu, 有数据没, 有数据没
不推荐使用
- server:
- from socket import *
- server = socket(AF_INET, SOCK_STREAM)
- server.bind(('127.0.0.1',8083))
- server.listen(5)
- server.setblocking(False) # 默认 True 阻塞
- print('starting...')
- rlist=[]
- wlist=[]
- while True:
- try: # 服务端不停得建链接
- conn, addr = server.accept()
- rlist.append(conn)
- print(rlist)
- except BlockingIOError: # 没阻塞
- # print('干其他的活')
- #收消息
- del_rlist = []
- for conn in rlist:
- try:
- data=conn.recv(1024)
- if not data:
- del_rlist.append(conn)
- continue
- wlist.append((conn,data.upper()))
- except BlockingIOError:
- continue
- except Exception:
- conn.close()
- del_rlist.append(conn)
- #发消息
- del_wlist=[]
- for item in wlist:
- try:
- conn=item[0]
- data=item[1]
- conn.send(data) # send 在数据量 过大时 也会阻塞
- del_wlist.append(item)
- except BlockingIOError:
- pass
- for item in del_wlist:
- wlist.remove(item)
- for conn in del_rlist:
- rlist.remove(conn)
- server.close()
- client:
- from socket import *
- client=socket(AF_INET,SOCK_STREAM)
- client.connect(('127.0.0.1',8083))
- while True:
- msg=input('>>:').strip()
- if not msg:continue
- client.send(msg.encode('utf-8'))
- data=client.recv(1024)
- print(data.decode('utf-8'))
- client.close()
4. 多路复用 io:
wait copy 还多了 select 中间有个中介存在, 帮问 os 有没有数据
但是如果中介 只有 1 个 效率不如 阻塞效率
但是如果中介监测多个套接字 , 性能高就是: 同时监测多个套接字问 os 系统好了没 就比阻塞 io 效率高
监测套接字得 io 行为
服务端得套接字有几类: server conn
select 阻塞 io 效率高
比非阻塞 io 效率也高 , 一直做无用
总结:
同时监测多个套接字
列表 循环 慢 假设列表数据多, 循环 效率低 监测套接字好没好 从头到尾 循环 1 遍
select 列表循环 效率低
poll 可接收得列表数据多 效率也不高
epoll 效率最高得 异步操作 每个套接字身上绑定个回调函数, 谁好了谁触发回调,(就不用去遍历了 效率低)
epoll windows 不支持
linux 支持
selectors 模块 自动根据操作系统选择
- poll
- epoll
- server:
- from socket import *
- import select
- server = socket(AF_INET, SOCK_STREAM)
- server.bind(('127.0.0.1',8083))
- server.listen(5)
- server.setblocking(False)
- print('starting...')
- rlist=[server,]
- wlist=[]
- wdata={}
- while True:
- rl,wl,xl=select.select(rlist,wlist,[],0.5) # [] 异常列表 每隔 0.5s 问一次
- print('rl',rl)
- print('wl',wl)
- for sock in rl:
- if sock == server:
- conn,addr=sock.accept()
- rlist.append(conn)
- else:
- try:
- data=sock.recv(1024)
- if not data:
- 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()
- client:
- from socket import *
- client=socket(AF_INET,SOCK_STREAM)
- client.connect(('127.0.0.1',8083))
- while True:
- msg=input('>>:').strip()
- if not msg:continue
- client.send(msg.encode('utf-8'))
- data=client.recv(1024)
- print(data.decode('utf-8'))
- client.close()
来源: http://www.bubuko.com/infodetail-2550810.html