IO多路复用
1,local:同一线程内,数据是共享的,loca可以产生线程ID,使数据隔离:
import time
import random
from threading import local,Thread
loc = local()
def func2():
global loc
print(loc.name,loc.age)
def func(name,age):
global loc
loc.name = name
loc.age = age
time.sleep(random.random())
func2()
Thread(target=func,args=('liming',22)).start()
Thread(target=func,args=('lijing',42)).start()
2.
同步:一件事情做完再做另一件
异步:同时做多件事情
阻塞:sleep,input,join,shutdown,wait,acquire,get
recv,recvfrom,accept
非阻塞:setblocking(False)
3网络IO模型
socket
用socket 一定会用到accept,recv,reccvfrom这些方法
正常情况下,recv,recvfrom,accept都是阻塞的
如果setblocking(False)这个程序就变成非阻塞
阻塞IO:recv做了哪些事情:
阻塞IO的recv,
wait for data阶段 阻塞
copy data 阶段 阻塞
非阻塞IO:
没有并发编程的机制
同步程序
非阻塞的特点
程序不会在某一个连接的recv或者sk的accept上进行阻塞
获得时间做信息的收发
非阻塞IO问题:占用cpu大量资源,给cpu造成很大的负担
阻塞IO问题:一旦阻塞,程序不往下执行
同时因为while True 高速运行着
大量的占用了CPU导致资源的浪费
import socket
sk = socket.socket()
sk.bind(('192.168.16.33',8088))
sk.setblocking(False) #设置当前的socket server 为一个非阻塞IO模型
sk.listen()
conn_1 = []
del_1 = []
while True:
try:
conn,addr = sk.accept()
conn_1.append(conn)
except BlockingIOError:
for conn in conn_1:
try:
conn.send(b'ok')
print(conn.recv(1024)) #收到对面的消息
except (NameError,BlockingIOError):
pass
except ConnectionAbortedError:
conn.close()
del_1.append(conn)
for del_conn in del_1:
conn_1.remove(del_conn)
del_1.clear()
import socket
sk = socket.socket()
sk.connect(('192.168.16.33',8088))
for i in range(1000000):
print(sk.recv(1024))
sk.send(b'hello')
sk.close()
4:IO多路复用:
IO阻塞一个没有消息,后面全部阻塞
IO非阻塞,即使没有消息,还在循环,永远在就绪与运行之间切换,能够最大限度利用cpu,但是不排除过度利用
IO多路复用,有消息就运行,没有就停止,操作系统提供的,一个代理,帮助监听网络IO对象,监听对象的读事件,写事件,特殊条件事件
异步IO:等待数据阶段和拷贝数据阶段都不需要用户处理,所有的操作都由操作系统完成,拷贝数据阶段,只有IO异步不需要阻塞
谁提供了你一个IO多路复用的机制?
操作系统提供的,python只是使用者
import select #模块
#用来操作操作系统中的select(IO多路复用)机制
# def select(rlist,wlist,xlist,timeout=None) 监听:读,写,特殊条件
import socket
sk = socket.socket()
sk.bind(('192.168.16.33',8088))
sk.setblocking(False)
sk.listen()
r_lst = [sk,]
while True:
r_l,_,_ = select.select(r_lst,[],[])
for item in r_l:
if item is sk:
conn,addr = sk.accept()
r_lst.append(conn)
else:
try:
print(item.recv(1024))
item.send(b'hello bb')
except ConnectionResetError:
item.close()
r_lst.remove(item)
import socket
sk = socket.socket()
sk.connect(('192.168.16.33',8088))
for i in range(1000000):
sk.send(b'hello')
print(sk.recv(1024))
sk.close()
IO多路复用机制:
select windows,mac\linux
底层是操作系统轮询
有监听对象个数的限制
随着监听对象的个数增加,效率降低
poll
底层是操作系统轮询
有监听对象个数的限制但是比select能监听的个数多
随着监听对象的个数增加,效率降低
epoll
给每一个要监听的对象都绑定了一个回调函数
不再受到个数增加,效率降低的影响
同点:
都是起到代理作用

浙公网安备 33010602011771号