IO模型

阻塞:遇到IO操作就会发生阻塞,程序一旦遇到阻塞操作停在原地,立刻释放cpu资源
非阻塞:没有遇到IO操作,或者通过某种手段让程序即便是遇到IO操作也不会停在原地,执行其他操作,力求尽可能多的占用cpu
阻塞,非阻塞(就绪,运行)
同步与异步指的是提交任务的两种方式
同步调用:提交任务后,停在原地等待,直到任务运行完毕后,拿到任务结果,才执行下一行代码
异步调用:提交任务后,不在原地等待,直接执行下一行代码

IO
本地IO和网络IO

网络IO的两种状态,wait_data,copy_data
copy_data 应用程序将要发送的信息copy给操作系统
当操作系统copy好信息后,copy_data就结束了
应用程序的send操作就完成了

IO模型:
1.阻塞IO
应用程序发起recvfrom ,发起系统调用,然后等待操作系统接收到信息后将信息从操作系统缓存copy到应用程序
wait_data,copy_data都在等待
2.非阻塞IO
设置s.setblocking = False
应用程序发起recvfrom,系统调用,系统回信号,没有数据
然后应用程序执行其他任务,
应用程序向操作系统不停发起recvfrom,直到等到数据
cpu占用率过高
非阻塞IO的关键在于捕捉,BlockingIOError

from socket import *
s = socket()
s.bind(("127.0.0.1",8888))
s.listen(5)
s.setblocking(False)
c_li = []
msg_li = []
while True:
    try:
        client,addr = s.accept()
        c_li.append(client)
    except BlockingIOError:#在所有阻塞的地方捕捉异常
        for c in c_li[:]:
            try:
                msg = c.recv(1024)
                if not msg:
                    c_li.remove(c)
                    continue
                msg_li.append((c,msg))
            except BlockingIOError:
                pass
            except ConnectionResetError:
                c_li.remove(c)
        for c_d in msg_li[:]:
            try:
                c_d[0].send(c_d[1])
                msg_li.remove(c_d)
            except ConnectionResetError:
                c_li.remove(c_d[0])
                msg_li.remove(c_d)

3.多路复用IO

import select
from socket import *
s = socket()
s.bind(("127.0.0.1",8888))
s.listen(5)
rlist = [s,]
wlist = []
msg_li = {}
while True:
    r_li,w_li,_ = select.select(rlist,wlist,[])
    for c in r_li:
        if c == s:
            client,addr = c.accept()
            rlist.append(client)
            continue
        try:
            msg = c.recv(1024)
            if not msg:
                rlist.remove(c)
                continue
            wlist.append(c)
            msg_li[c] = msg
        except ConnectionResetError:
            rlist.remove(c)
    for client in w_li:
        try:
            client.send(msg_li[client])
            wlist.remove(client)
        except ConnectionResetError:
            wlist.remove(client)

通过select模块检测IO,不会过高占用CPU

4.异步IO

posted @ 2019-01-06 21:54  robertzhou  阅读(126)  评论(0编辑  收藏  举报