今日内容概要
IO模型简介
"""
五种IO Model:
* blocking IO 阻塞IO
* nonblocking IO 非阻塞IO
* IO multiplexing IO多路复用
* signal driven IO 信号驱动IO
* asynachronous IO 异步IO
"""
常见的网络阻塞状态:
accept
recv
recvfrom
阻塞IO模型
import socket
server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.listen(5)
while True:
conn, addr = server.accept()
while True:
try:
data = conn.recv(1024)
if len(data) ==0:break
print(data)
conn.send(data.upper())
except ConnectionResetErroe as e:
break
conn.close()
非阻塞IO
import socket
import time
server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.liten(5)
server.setblockding(False)
# 将所有的网络阻塞变为非阻塞
# 服务端
r_list = []
del_list = []
while True:
try:
conn, addr = server.accept()
r_list.append(conn)
except BlockingIOError:
for conn in r_list:
try:
data = conn.recv(1024) # 没有消息 报错
if len(data) == 0:
conn.close()
del_list.append(conn)
continue
conn.send(data.upper())
except BlockingIOError:
conn.close()
def_list.append(conn)
for conn in del_list:
r_list.remove(conn)
def_list.clear()
# 客户端
import socket
client = socket.socket()
client.connect(('127.0.0.1', 8080))
while True:
cliend.send(b'hello world')
data = client.recv(1024)
print
# 总结
"""
非阻塞IO模型会长时间占用着CPU并且不干活,让CPU不停的空转
实际应用中不会考虑使用非阻塞IO模型
"""
IO多路复用
"""
当监管的对象只有一个时,IO多路复用连阻塞IO都比不上
但是IO多路复用可以一次性监管很多对象
"""
import socket
import select
server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.listen(5)
server.setblocking(False)
read_list = [server]
while True:
r_list, w_list, x_list =select.select(read_list, [], [])
for i in r_list:
if i is server:
conn, addr = i.accept()
read_list.append(conn)
else:
res = i.recv(1024)
if len(res) == 0:
i.close()
read_list.remove(i)
continue
print(res)
i.send(b'hahahahaha')
# 客户端
import socket
client = socket.socket()
client.connect(('127.0.0.1', 8080))
while True:
client.send(b'hello world')
data = client.recv(1024)
print(data)
异步IO
"""
异步IO模型是所有模型中效率最高的,也是使用最广泛的
相关的模块和框架
模块:asyncio模块
异步框架:sanic tronado twisted
速度快
"""
import threading
import asyncio
@asyncio.coroutine
def hello():
print('hello world %s' % threading.current_thread())
yield from asyncio.sleep(1) # 换成真正的IO操作
print('hello world %s' % threading.current_thread())
loop = asyncio.get_event_loop()
tasks = [hello(), hello()]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()