网络IO模型 socket
blocking IO 阻塞IO 平时用的TCP/UDP
nonblockingIO 非阻塞IO
IOmultiplexing IO多路复用 *****
asynchronous IO异步IO python中已经有异步的框架了
网络IO
输入 : recv accept recvfrom
输出 : send sendto sendall connect 等待时间
阻塞会给我们的程序带来哪些影响?
1.进程调度 阻塞的IO会让整个进程都进入阻塞状态
2.tcp协议中,一个任务阻塞之后,整个线程/进程/协程都阻塞了,其他任务都不能被执行了
1 . 阻塞IO :
阻塞IO接收并发请求 : 多线程/多进程
2 . 非阻塞IO :
非阻塞IO实现的tcp协议:
服务端:
import socket
sk = socket.socket()
sk.bind(("127.0.0.1",9090))
sk.setblocking(False)
sk.listen()
li = []
l = []
while 1:
try:
conn,addr = sk.accept()
li.append(conn)
except Exception as e:
for conn in li:
try:
ret = conn.recv(1024)
if ret:
print(ret)
conn.send(b"hello")
else:
conn.close()
l.append(conn)
except Exception as e:pass
for conn in l:
li.remove(conn)
l.clear()
客户端 :
import socket
sk = socket.socket()
sk.connect(("127.0.0.1",9090))
for i in range(10000):
sk.send(b"hello")
print(sk.recv(1024))
sk.close()
3 . IO多路复用 --- 操作系统提供的
1.程序不能干预过程
2.操作系统之间的差异
import socket , select
sk = socket.socket()
sk.bind(("127.0.0.1",9090))
sk.setblocking(False)
sk.listen()
li = [sk]
while 1:
rl , wl , sl = select.select(li , [] , [])
#为什么突然把sk返回回来了?sk对象有数据可以被读了
#为什么返回三个列表?读事件的列表 写事件列表 条件的列表
#为什么是列表?有可能同时有多个被监听的对象发生读事件
for obj in rl:
if obj is sk:
conn,addr = sk.accept()
li.append(conn)
else:
try:
ret = obj.recv(1024)
print(ret)
obj.send(b"hello")
except Exception as e:
obj.close()
li.remove(obj)
对于TCP协议来说 , 如果对方关闭了连接 , 另一方有可能继续接收 空消息 或者 报错
什么叫IO多路复用?
IO多路复用是操作系统提供的一种 监听 网络IO操作的机制
监听三个列表 当某一个列表有对应的事件发生的时候 , 操作系统通知应用程序 ; 操作系统根据返回的内容做具体的操作
对于只有一个对象需要监听的情况 IO多路复用并无法发挥作用
对于并发接收网络请求的应用场景 IO多路复用可以帮助我们在节省CPU利用率和操作系统调用的基础上完成并发需求
IO多路复用 :
select : 是Windows上的机制 操作系统使用轮询的方式来监听每一个对象是否有对应的事件发生的,数据越多延迟越大 ,能够处理的对象数是有限的
poll : Linux系统 和select的机制基本一致,对底层存储被监听对象的数据结构做了优化 ,能够处理的对象个数增加了
epoll : linux系统 采用了回调函数的方式来通知应用被监听的对象有事件发生了.