IO模型 IO多路复用

阻塞IO

用socket 一定会用到accept recv recvfrom这些方法
正常情况下 accept recv recvfrom都是阻塞的

非阻塞IO

如果setblocking(False) 整个程序就变成一个非阻塞的程序了
非阻塞的特点:
  没有并发编程的机制
  是一个同步的程序
  程序不会在某一个连接的recv或者sk的accept上进行阻塞
缺点:
  太多while True 高速运行着
  大量的占用了CPU导致了资源的浪费
阻塞IO的问题:
一旦阻塞就不能做其他事情了
非阻塞IO的问题:
给CPU造成了很大的负担

import time
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',9000))
sk.setblocking(False)   # 设置当前的socket server为一个非阻塞IO模型
sk.listen()
conn_l = []
del_l = []
while True:
    try:
        conn,addr = sk.accept()
        conn_l.append(conn)   # [conn1,conn2]
    except BlockingIOError:
        for conn in conn_l:   # [conn1,conn2]
            try:
                conn.send(b'hello')
                print(conn.recv(1024))
            except (NameError,BlockingIOError):pass
            except ConnectionResetError:
                conn.close()
                del_l.append(conn)
        for del_conn in del_l:
            conn_l.remove(del_conn)
        del_l.clear()

 IO多路复用

io多路复用机制
select windows、mac\linux
底层是操作系统的轮询
有监听对象个数的限制
随着监听对象的个数增加,效率降低
poll mac\linux
底层是操作系统的轮询
有监听对象个数的限制,但是比select能监听的个数多
随着监听对象的个数增加,效率降低
epoll mac\linux
给每一个要监听的对象都绑定了一个回调函数
不再受到个数增加 效率降低的影响

import select  #  模块 用来操作操作系统中的select(IO多路复用)机制
import socket

sk = socket.socket()
sk.bind(('127.0.0.1',9000))
sk.setblocking(False)
sk.listen()

r_lst = [sk,]
print(sk)
while True:
    r_l,_,_ = select.select(r_lst,[],[])  # r_lst = [sk,conn1,conn2,conn3]
    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')
            except ConnectionResetError:
                item.close()
                r_lst.remove(item)

猜你喜欢

转载自www.cnblogs.com/qq752059037/p/9714419.html