zoukankan      html  css  js  c++  java
  • 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.同时程序也处于异步执行状态

      

      

  • 相关阅读:
    [ jquery 选择器 :hidden ] 此方法选取匹配所有不可见元素,或者type为hidden的元素
    剑指 Offer 03. 数组中重复的数字 哈希
    LeetCode 1736. 替换隐藏数字得到的最晚时间 贪心
    Leetcode 1552. 两球之间的磁力 二分
    Leetcode 88. 合并两个有序数组 双指针
    LeetCode 1744. 你能在你最喜欢的那天吃到你最喜欢的糖果吗?
    LeetCode 1743. 相邻元素对还原数组 哈希
    LeetCode 1745. 回文串分割 IV dp
    剑指 Offer 47. 礼物的最大价值 dp
    剑指 Offer 33. 二叉搜索树的后序遍历序列 树的遍历
  • 原文地址:https://www.cnblogs.com/lianyeah/p/9715100.html
Copyright © 2011-2022 走看看