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

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

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

同点:

  都是起到代理作用

原文地址:https://www.cnblogs.com/lijinming110/p/9714660.html