IO常用四种模型

阻塞IO模型(blocking IO)

在这里插入图片描述

因为通信的时候,数据是先复制到系统,再通过网线发送的,所以,recv在等待接受数据的时候,会先跟内核/操作系统要数据。进而出现两个等待过程,一个是系统等待对方发送数据、一个是应用程序等待系统的数据拷贝过来。


在这里插入图片描述

非阻塞IO(unLocking IO)

非阻塞IO是通过不断轮询,直到操作系统拿到数据,把数据拷贝给应用程序,但是,在操作系统将数据拷贝给用户进程的过程还是会被阻塞的(block)。

 注意:需要关闭阻塞,server.setblocking(False)

在这里插入图片描述

缺点:这种方式会提高cpu占用率,同时,如果出现轮询第二个的时候,第一个人连接成功,这时候,要等待轮询结束后,重新开始轮询才可以轮到第一个人通话,这样会增加等待时间。
优点:能够在等待的过程做其他事情。

多路复用IO(multiplexing IO)

多路复用IO,基本原理就是把非阻塞IO的轮询操作给select/epoll来执行,当有数据到达的时候,就会通知用户进程。
用户进程调用select的时候,就会进入阻塞状态,直到监听的对象有数据过来,才会进行下一步将数据拷贝到进程。


在这里插入图片描述

注意:多路复用IO只有在处理多连接的时候才有优势。在处理单链接的优势不及阻塞IO。

#服务端
# -*-coding:utf-8 -*-
import socket
import select


server=socket.socket()
server.bind(('localhost',8080))
server.listen(5)
server.setblocking(False)
read_list=[server]
while True:
    r_list,w_list,x_list=select.select(read_list,[],[])
    print(r_list)
    for li in r_list:
        if li == server:
            conn,addr=li.accept()
            read_list.append(conn)
        else:
            data=li.recv(1024)
            print(data)
            li.send(data.upper())
#客户端
import socket


c=socket.socket()
c.connect(('localhost',8080))
while True:

    c.send('hello world'.encode())
    data=c.recv(1024)
    print(data)

异步IO(asynchronous IO)

原理:有点类似回调机制,用户进程发起read操作后,就不再等待,而是继续执行其他任务,等read操作全部完成后,会发送一个信号告诉用户进程read操作完成。在这个过程中不会对用户进程产生任何阻塞(IO)
在这里插入图片描述

posted @ 2020-09-16 15:14  NQ31  阅读(116)  评论(0编辑  收藏  举报