IO模型

IO模型--自己实现IO
目的--在单个线程里面把IO降下来

IO两个阶段
--等待数据准备
--从内核把数据拷贝到进程中

网络IO
blocking IO--阻塞IO
特点--在IO执行的两个阶段都被阻塞

nonblocking IO--非阻塞IO,利用了等待数据准备的阶段
优点--能够在等待任务的完成时间内去干其他的活
但是绝不推荐使用
非阻塞IO实现套接字通信:
from socket import *
import time

s = socket()
s.bind(("127.0.0.1",8077))
s.listen(5)
s.setblocking(False)    # 参数默认是Ture--阻塞IO,设为Flase--非阻塞IO
conn_l = []

while True:
    del_l = []
    try:
        conn,addr = s.accept()
        print("%s:%s"%(addr[0],addr[1]))
        conn_l.append(conn)
    except BlockingIOError:
        print("没有数据")
        time.sleep(2)   # 循环调用recv能大幅提高cpu占用率,所以睡一下
        for conn in conn_l:
            try:
                data = conn.recv(1024)
                conn.send(data.upper())

            except BlockingIOError: # 阻塞的时候直接pass掉这个连接,继续for循环下一个连接,没必要去写continue
                pass
            except ConnectionResetError:    # 当客户端单方面关闭时,把已关闭的连接加到del_l列表中,等下去删除
                del_l.append(conn)
        for conn in del_l:
            del_l.remove(conn)  # 删除已经关闭的连接,并且关闭该连接
            conn.close()
server端
from socket import *

c = socket()
c.connect(("127.0.0.1",8077))

while True:
    msg = input(">>>")
    if not msg:continue
    c.send(msg.encode("utf-8"))
    data = c.recv(1024)
    print(data.decode("utf-8"))
client端

 

    IO multiplexing--多路复用IO
也是利用了等待数据准备的阶段

select模块--提供了select模型---单个进程可以同时处理多个网络连接的IO
效率最高--epoll模型(windows不支持)-- 基于Linux操作系统的,

只监测连接数不死很高的时候,效率很低
优势在于处理多个链接

多路复用IO实现套接字通信:

from socket import *
import select

s = socket()
s.bind(("127.0.0.1",8077))
s.listen(5)
s.setblocking(False)    # 参数默认是Ture--阻塞IO,设为Flase--非阻塞IO
read_list = [s,]    # 放已经建立的连接

while True:
    r_l,_,_ = select.select(read_list,[],[])
    # r_l,w_l,x_l = select.select(read_list,[],[])
    # r_l表示准备好读的,w_l表示准备好写的,具体看select模块

    for obj in r_l:
        if obj == s:
            conn,addr = obj.accept()
            read_list.append(conn)
        else:
            try:
                data = obj.recv(1024)
                if not data:
                    obj.close()
                    read_list.remove(obj)
                    continue
                obj.send(data.upper())
            except ConnectionResetError:
                obj.close()
                read_list.remove(obj)
server端
from socket import *

c = socket()
c.connect(("127.0.0.1",8077))

while True:
    msg = input(">>>")
    if not msg:continue
    c.send(msg.encode("utf-8"))
    data = c.recv(1024)
    print(data.decode("utf-8"))
client端

 

    ansychronous IO--异步IO
充分用了等待数据准备阶段和拷贝数据阶段


signal driven IO--信号驱动IO
posted @ 2017-10-18 15:37  chitalu  阅读(98)  评论(0)    收藏  举报