zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    java23种设计模式-结构型模式-适配器模式
    java23种设计模式-创建者模式-抽象工厂模式
    java23种设计模式-创建者模式-工厂模式
    从jvm运行数据区分析字符串是否相同
    Linux常见安全策略
    MySQL 报错案例分析
    Linux系统网络监控工具
    海量运维架构
    Linux运维面试技巧
    DBA机遇于风险并存
  • 原文地址:https://www.cnblogs.com/robert-zhou/p/10230558.html
Copyright © 2011-2022 走看看