zoukankan      html  css  js  c++  java
  • IO多路复用

    1,local:同一线程内,数据是共享的,loca可以产生线程ID,使数据隔离:

    import time
    import random
    from threading import local,Thread
    loc = local()
    def func2():
        global loc
        print(loc.name,loc.age)
    
    def func(name,age):
        global loc
        loc.name = name
        loc.age = age
        time.sleep(random.random())
        func2()
    Thread(target=func,args=('liming',22)).start()
    Thread(target=func,args=('lijing',42)).start()
    

     

    2.

      同步:一件事情做完再做另一件

      异步:同时做多件事情

      阻塞:sleep,input,join,shutdown,wait,acquire,get

        recv,recvfrom,accept

      非阻塞:setblocking(False)

    3网络IO模型

      socket

      用socket 一定会用到accept,recv,reccvfrom这些方法

      正常情况下,recv,recvfrom,accept都是阻塞的

      如果setblocking(False)这个程序就变成非阻塞

    阻塞IO:recv做了哪些事情:

      阻塞IO的recv,

        wait for data阶段 阻塞

        copy data 阶段  阻塞

    非阻塞IO:

    没有并发编程的机制

    同步程序

    非阻塞的特点

    程序不会在某一个连接的recv或者sk的accept上进行阻塞

    获得时间做信息的收发

    非阻塞IO问题:占用cpu大量资源,给cpu造成很大的负担

    阻塞IO问题:一旦阻塞,程序不往下执行

      同时因为while True 高速运行着

      大量的占用了CPU导致资源的浪费

    import socket
    sk = socket.socket()
    sk.bind(('192.168.16.33',8088))
    sk.setblocking(False) #设置当前的socket server 为一个非阻塞IO模型
    sk.listen()
    conn_1 = []
    del_1 = []
    while True:
        try:
            conn,addr = sk.accept()
            conn_1.append(conn)
        except BlockingIOError:
            for conn in conn_1:
                try:
                        conn.send(b'ok')
                        print(conn.recv(1024)) #收到对面的消息
                except (NameError,BlockingIOError):
                    pass
                except ConnectionAbortedError:
                    conn.close()
                    del_1.append(conn)
            for del_conn in del_1:
                conn_1.remove(del_conn)
                del_1.clear()
    

      

    import socket
    sk = socket.socket()
    sk.connect(('192.168.16.33',8088))
    
    for i in range(1000000):
        print(sk.recv(1024))
        sk.send(b'hello')
    sk.close()
    

      

    4:IO多路复用:

      IO阻塞一个没有消息,后面全部阻塞

      IO非阻塞,即使没有消息,还在循环,永远在就绪与运行之间切换,能够最大限度利用cpu,但是不排除过度利用

      IO多路复用,有消息就运行,没有就停止,操作系统提供的,一个代理,帮助监听网络IO对象,监听对象的读事件,写事件,特殊条件事件

      异步IO:等待数据阶段和拷贝数据阶段都不需要用户处理,所有的操作都由操作系统完成,拷贝数据阶段,只有IO异步不需要阻塞

    谁提供了你一个IO多路复用的机制?

      操作系统提供的,python只是使用者

      

    import select #模块
    #用来操作操作系统中的select(IO多路复用)机制
    # def select(rlist,wlist,xlist,timeout=None) 监听:读,写,特殊条件
    import socket
    sk = socket.socket()
    sk.bind(('192.168.16.33',8088))
    sk.setblocking(False)
    sk.listen()
    
    r_lst = [sk,]
    while True:
        r_l,_,_ = select.select(r_lst,[],[])
        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 bb')
                except ConnectionResetError:
                    item.close()
                    r_lst.remove(item)
    

      

    import socket
    sk = socket.socket()
    sk.connect(('192.168.16.33',8088))
    
    for i in range(1000000):
        sk.send(b'hello')
        print(sk.recv(1024))
    
    sk.close()
    

      

    IO多路复用机制:

    select    windows,maclinux

      底层是操作系统轮询

      有监听对象个数的限制

      随着监听对象的个数增加,效率降低

    poll

      底层是操作系统轮询

      有监听对象个数的限制但是比select能监听的个数多

      随着监听对象的个数增加,效率降低

    epoll

      给每一个要监听的对象都绑定了一个回调函数

      不再受到个数增加,效率降低的影响

    同点:

      都是起到代理作用

  • 相关阅读:
    docker安装kafka
    Prometheus警报
    MongoDB介绍
    SpringMvc中几个注解
    无DNS安装VCSA
    互联网本质
    什么是领导力
    58沈剑_一分钟专栏
    以数据库思维理解区块链
    区块链的4个实际应用
  • 原文地址:https://www.cnblogs.com/lijinming110/p/9714660.html
Copyright © 2011-2022 走看看