• Day38 python基础--并发编程基础-IO模型


    一,IO模型,这里的指的是linux环境下networl IO

      1.blocking IO  (阻塞IO)

      2.nonblocking IO (非阻塞IO)

      3.IO multiplexing  (IO多路复用)

      4.asynchronous IO  (异步IO)

      5.signal driven IO  (信号驱动IO) 在实际中并不常用,所以主要介绍其余四种IO模型

      IO发生时涉及的对象和步骤:对于一个network IO (以read为例,即类似recv操作),他会涉及到两个系统对象,一个是调用这个IO的process(or thread),另一个就是系统内核(kernel)。当一个read操作发生时,该操作会经历两个阶段:

      1.等待数据准备(waiting for the data to be ready)

      2.将数据从内核拷贝到进程中(copying the data from the kernel to the process)

      这些IO模型的区别就是在这个两个阶段上各有不同的情况

      

      网络IO的阻塞与非阻塞

        socket:

          1.用socket一定会用到accept,recv,recvfrom这些方法

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

          3.如果setblocking(False),整个程序就变成一个非阻塞的程序

    二,阻塞IO模型

      阻塞IO的recv

        wait for data阶段--阻塞

        copy data 阶段--阻塞

      缺点:一旦阻塞就不能做其他事情了

    三,非阻塞IO模型

      缺点:对cpu造成很大的负担

      非阻塞IO模型:

        1.没有并发编程的机制

        2.同步的程序

        3.非阻塞的特点

        4.程序不会在某一个连接的recv或者sk的accept上进行阻塞,可以有更多的时间来做信息的收发工作

        5.但是一直在执行while True,会大量的占用了cpu导致了资源的浪费,对cpu负担较大

    #非阻塞IO
    import time
    import socket
    sk = socket.socket()
    sk.bind(('127.0.0.1',9000))
    sk.setblocking(False)   # 设置当前的socket server为一个非阻塞IO模型
    sk.listen()
    conn_l = []
    del_l = []
    while True:
        try:
            conn,addr = sk.accept()
            conn_l.append(conn)   # [conn1,conn2]
        except BlockingIOError:
            for conn in conn_l:   # [conn1,conn2]
                try:
                    conn.send(b'hello')
                    print(conn.recv(1024))
                except (NameError,BlockingIOError):   #由于recv非阻塞,没有收到信息就会报错blockingioerror,nameerror处理conn的报错
              pass except ConnectionResetError: #当客户端中断连接时,异常处理 conn.close() del_l.append(conn) for del_conn in del_l: conn_l.remove(del_conn) del_l.clear()

    四,IO多路复用

      1.select:window/mac/linux均支持

        底层是操作系统的轮询

        有监听对象个数的限制

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

      2.poll:mac/linux均支持

        底层是操作系统的轮询

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

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

      3.epoll:mac/linux均支持

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

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

      IO复用的应用:

        socketserver:IO多路复用+threading线程

      拓展:selectors模块

        帮助你在不同的操作系统上进行IO多路复用机制的自动筛选

    import select  #  模块
    import socket
    # 用来操作操作系统中的select(IO多路复用)机制
    sk = socket.socket()
    sk.bind(('127.0.0.1',9000))
    sk.setblocking(False)
    sk.listen()
    
    r_lst = [sk,]
    print(sk)
    while True:
        r_l,_,_ = select.select(r_lst,[],[])  # r_lst = [sk,conn1,conn2,conn3]
        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')
                except ConnectionResetError:
                    item.close()
                    r_lst.remove(item)

     五,异步IO:

      1.通知操作系统,程序正在等待消息

      2.操作系统监听到消息后,copy数据到内核后,直接推送到程序内存中

      3.同时程序也处于异步执行状态

      

      

  • 相关阅读:
    选择排序——Selection Sort
    Android使用AIDL跨进程通信
    Android Gradle Plugin Version和Gradle Version 对应关系
    error: device unauthorized —— android studio 链接不上虚拟机
    Touch事件传递机制 Android
    Activity生命周期
    Error:Could not determine the class-path for interface com.android.builder.model.AndroidProject.
    Error:fatal: Not a git repository (or any of the parent directories): .git
    Installation failed with message...It is possible that this issue is resolved by uninstalling an existing version of the apk if it is present, and then re-installing.
    Ajax 学习总结
  • 原文地址:https://www.cnblogs.com/lianyeah/p/9715100.html
Copyright © 2020-2023  润新知