zoukankan      html  css  js  c++  java
  • io模型

    首先复习了基于协程实现的套接字通信:

    #服务端
    from gevent import monkey,spawn;monkey.patch_all()
    
    from socket import *
    
    
    def lack(conn):
        while True:
            try:
                data=conn.recv(1024)
                if not data:break
                conn.send(data.upper())
            except ConnectionResetError:
                break
        conn.close()
    
    def server(ip,port,count=5):
        s=socket()
        s.bind((ip,port))
        s.listen(count)
    
        while True:
            conn,addr=s.accept()
            g=spawn(lack,conn)
    
    
    
    if __name__ == '__main__':
        spawn(server,'192.168.12.81', 5050).join()
    
    
    #客户端
    from threading import Thread,current_thread
    
    from socket import *
    
    
    def client():
        client = socket()
        client.connect(('192.168.12.81', 5050))
        while True:
            client.send(('%s is running'%current_thread().name).encode('utf-8'))
            data=client.recv(1024)
            print(data.decode('utf-8'))
    
    if __name__ == '__main__':
        for i in range(10):
            t=Thread(target=client)
            t.start()

    异步io

    from concurrent.futures import ThreadPoolExecutor
    from threading import current_thread
    import time
    import os
    
    def task(n):
        print('%s is running' %current_thread().name)
        time.sleep(2)
        return n**2
    
    def parse(obj):
        res=obj.result()
        print(res)
    
    if __name__ == '__main__':
        t=ThreadPoolExecutor(4)
    
        future1=t.submit(task,1)
        future1.add_done_callback(parse) #parse函数会在future1对应的任务执行完毕后自动执行,会把future1自动传给parse
    
        future2=t.submit(task,2)
        future2.add_done_callback(parse)
    
        future3=t.submit(task,3)
        future3.add_done_callback(parse)
    
        future4=t.submit(task,4)
        future4.add_done_callback(parse)

    io模型

        Stevens在文章中一共比较了五种IO Model:
        * blocking IO
        * nonblocking IO
        * IO multiplexing
        * signal driven IO
        * asynchronous IO
        由signal driven IO(信号驱动IO)在实际中并不常用,所以主要介绍其余四种IO Model。

    阻塞io模型:

    #服务端
    import socket
    
    server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    server.bind(('192.168.12.81', 5050))
    server.listen(5)
    
    while True:
        conn,addr=server.accept()
    
        while True:
            try:
                data=conn.recv(1024)
                if not data: break
                conn.send(data.upper())
            except ConnectionResetError:
                break
        conn.close()
    server.close()
    
    
    #客户端
    import socket
    
    client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    client.connect(('192.168.12.81', 5050))
    
    while True:
        msg=input('>>:').strip()
        client.send(msg.encode('utf-8'))
        res=client.recv(1024)
        print(res.decode('utf-8'))
    client.close()

     我们最初写的基于网络传输的套接字就是阻塞io

    非阻塞io模块:

    #服务端
    from socket import *
    
    s=socket()
    s.bind(('192.168.12.81', 5050))
    s.listen(5)
    s.setblocking(False)
    
    r_list=[]
    w_list=[]
    while True:
        try:
            conn,addr=s.accept()
            r_list.append(conn)
    
        except BlockingIOError:
            print('rlist:',len(r_list))
    
            del_rlist=[]
            for conn in r_list:
                try:
                    data=conn.recv(1024)
                    if not data:
                        conn.close()
                        del_rlist.append(conn)
                        continue
                    w_list.append((conn,data.upper()))
                except BlockingIOError:
                    continue
                except ConnectionResetError:
                    conn.close()
                    del_rlist.append(conn)
    
            del_wlist=[]
            for item in w_list:
                try:
                    conn=item[0]
                    res=item[1]
                    conn.send(res)
                    del_wlist.append(item)
                except BlockingIOError:
                    continue
                except ConnectionResetError:
                    conn.close()
                    del_wlist.append(item)
            for conn in del_rlist:
                r_list.remove(conn)
    
            for item in del_wlist:
                w_list.remove(item)
    #客户端
    from socket import *
    import os
    
    
    c=socket()
    c.connect(('192.168.12.81', 5050))
    
    while True:
        data='%s say hello'%os.getpid()
        c.send(data.encode('utf-8'))
        res=c.recv(1024)
        print(res.decode('utf-8'))

    多路复用io:

    #服务端
    from socket import *
    import select
    
    s=socket()
    s.bind(('192.168.12.81', 5050))
    s.listen(5)
    s.setblocking(False)
    
    r_list=[s,]
    w_list=[]
    w_data={}
    while True:
        print('被检测r_list: ', len(r_list))
        print('被检测w_list: ', len(w_list))
        r1,w1,x1=select.select(r_list,w_list,[],)
    
    
        for r in r1:
            if r==s:
                conn,addr=r.accept()
                r_list.append(conn)
            else:
                try:
                    data=r.recv(1024)
                    if not data:
                        r.close()
                        r_list.remove(r)
                        continue
                    w_list.append(r)
                    w_data[r]=data.upper()
                except ConnectionResetError:
                    r.close()
                    r_list.remove(r)
                    continue
    
    
        for w in w1:
            w.send(w_data[w])
            w_list.remove(w)
            w_data.pop(w)
    
    #客户端
    from socket import *
    import os
    
    client=socket()
    client.connect(('192.168.12.81', 5050))
    
    
    while True:
        data='%s say hello'%os.getpid()
        client.send(data.encode('utf-8'))
        res=client.recv(1024)
        print(res.decode('utf-8'))

    多路复用io单进程的情况下,效率比阻塞io还要低,它的作用是在多个进程的情况下 体现的

    异步io模块:

    异步io模块的效率最高

  • 相关阅读:
    zbb20170621 linux CentOS 7上安装jdk时提示:/lib/ld-linux.so.2: bad ELF interpreter
    zbb20170620 eclipse tomcat 临时目录
    zbb20170619 bat cmd 脚本相关
    zbb20170613 linux 安装 mysql
    1.1 Eclipse的安装
    2、数据库和数据库表操作
    1、MySql的安装和连接测试并给root用户赋密码
    1、SpringMVC+MyBaits实现查询所有
    1、第一个SpringMVC程序
    2.SSH 两个表全套增删改(运动员住宿管理)
  • 原文地址:https://www.cnblogs.com/yftzw/p/8981830.html
Copyright © 2011-2022 走看看