说说基于网络的五种IO模型

  

# django不是一个异步框架
# tornado是异步的web框架
    # 处理每秒大量的请求

# 个人理解的IO:就是应用层与内核驱动层的交互,这个过程无论从应用层到内核中,还是驱动层等待硬件层的数据,都是需要时间的,这个过程是IO操作过程

# 五种IO Model
    # blocking IO  阻塞IO
    # nonblocking 非阻塞IO
    # IO multiplexing IO多路复用
    # signal driven IO 信号驱动IO
    # asynchronous IO 异步IO
        # 在python中没有提供异步IO的机制,没有操作系统将数据直接给应用层的获取到数据的接口. 但是由很多python的异步框架
        # 这种异步IO机制其实是很好的
# IO发生时涉及的对象和步骤,对于一个network IO,我们以read举例,他会涉及到两个系统对象,一个是调用这个IO的process(or thread),另一个就是系统内核。当一个read操作时,该操作会经历两个阶段
    # 1.等待数据准备
    # 2.将数据从内核拷贝到应用层
# 同步    提交一个任务之后要等待这个任务执行完毕才能继续执行其他的
# 异步    只管提交任务,不用等待该任务执行完毕就可以继续做其他事情
# 阻塞    运行状态 -> 阻塞状态 -> 就绪状态 -> 运行状态、一进程或线程阻塞则会进入阻塞状态休眠
# 非阻塞

  1.非阻塞IO

# 非阻塞IO
# import socket
# sk = socket.socket()
# sk.setblocking(False)   # 设置非阻塞
# sk.bind((‘127.0.0.1‘, 8080))
# sk.listen()
#
# try:
#     conn, addr = sk.accept()  # 因为将套接字设置为了非阻塞,所以这里会报错,因为accept不允许为非阻塞性的,所以下面捕捉异常,有异常则直接pass
#     print(‘有客户端连接上来 ‘)
# except BlockingIOError:
#     pass

  2.阻塞IO

  3.IO多路复用

    # 在windows、linux上,有一个select专门提供IO多路复用的。
    # poll机制    # linux上有
    # epoll机制   # linux上有
    # poll机制和epoll机制使用方法和select一样
        # poll可以监听的对象比select可以监听的多。如果select能监听500,则poll能监听1000个类似这样
        # poll和select都是操作系统去轮询机制的监听被监听的项,看是否有读操作等,随着监听列表增多,会导致效率变差
        # epoll机制
            # 给每一个被监听的对象都绑定了一个回调函数,当被监听的对象有监听事件后,会触发此监听对象绑定的回调函数这种机制比select和poll的轮询效率要高,高并发非常有用
    # import selectors 这个模块会帮助你选择当前操作系统上最优的IO多路复用

  3.1 IO多路复用中的select

  服务端

import select   # 内置的select模块,用于IO多路复用
import socket
# select.select(rlist, wlist, xlist, timeout=None)
    # 参数是3个列表,一个监听超时时间
    # rlist参数,表示监听读,直到监听到读或超时返回
    # wlist参数,表示监听写,直到监听到写或超时返回
    # xlist参数,表示监听条件
    # timeout参数,监听超时时间
    # 返回值有三个
sk = socket.socket()
sk.bind((‘127.0.0.1‘, 8080))
sk.setblocking(False)   # 设置为非阻塞
sk.listen()

read_lst = [sk] # 创建一个列表,想要监听谁,则将哪个对象放进来,这里开始先监听socket对象,当有人向这个socket发起连接的时候,select则会监听到返回一个socket
while 1:
    # 调用select后操作系统会帮你监听三个监听列表,这里监听的是监听读列表
    r_lst, w_lst, x_lst = select.select(read_lst, [], [])   # 当监听到后,返回一个元组,元组中有三个元素,分别是rlist,wlist,xlist。这里rlist中最开始监听sk,因此当有客户端连接上来后,会监听有要被读的事件,这里会返回得到一个r_lst,r_lst中有一个sk对象
    #print(r_lst)
    for i in r_lst:
        if i is sk: # 判断监听到的对象是否是sk对象
            conn, addr = i.accept() # 此时直接sk.accpet()就会得到客户端连接和地址
            read_lst.append(conn)   # 将客户端连接符加入到监听列表中
        else:   # 如果监听到的不是sk对象, 这里的第二可能是监听到了客户端连接符有要被读的事件
            msg = i.recv(1024)
            if msg == b‘‘:  # 当客户端连接关闭时,会接收到空的数据,
                i.close()   # 因为客户端连接主动关闭,这里也要关闭下这个客户端连接
                read_lst.remove(i)  # 同时在监听列表中去除这个客户端连接符,不再去监听它
                continue
            print(msg)

  3.2 linux上更好的IO多路复用epoll、selectors选择当前系统最优的IO多路复用机制

  服务端

# linux上的selectors IO多路复用机制,IO多路复用机制,默认选择系统最优,linux上肯定选择epoll
import selectors
from socket import *

def read(conn, mask):
    ‘‘‘
    将来要绑定的回调函数
    :param conn:
    :param mask:
    :return:
    ‘‘‘
    try:
        data = conn.recv(1024)
        if not data:    # 如果监听客户端的数据是空数据,则表示客户端连接关闭了
            print(‘closeing‘, conn)
            sel.unregister(conn)    # 在监听列表中去除这个客户端连接的监听
            conn.close()    # 同时服务端也关闭这个客户端连接描述符
            return
        conn.send(data.upper() + b‘SB‘)
    except Exception:   # 该客户端连接描述符监听到异常事件,则直接关闭客户端连接
        print(‘closing‘, conn)
        sel.unregister(conn)  # 在监听列表中去除这个客户端连接的监听
        conn.close()  # 同时服务端也关闭这个客户端连接描述符

def accept(server_fileobj, mask):
    ‘‘‘

    :param server_fileobj:  接收到的socket
    :param mask:
    :return:
    ‘‘‘
    conn, addr = server_fileobj.accpet()    # 得到客户端连接描述符
    sel.register(conn, selectors.EVENT_READ, read)  # 将conn客户端连接符注册到监听列表中,监听的是其读时间,绑定的回调函数是read

if __name__ == ‘__main‘:
    sk = socket()
    sk.setblocking(SOL_SOCKET, SO_REUSEPORT, 1)
    sk.bind((‘127.0.0.1‘, 8080))
    sk.listen(5)
    sk.setblocking(False)
    sel = selectors.DefaultSelector()   # 获取到当前操作系统最优的IO多路复用机制
    sel.register(sk, selectors.EVENT_READ, accept)  # 将socket对象注册到监听列表中,监听其读事件,当有读事件时绑定的回调函数accpet会被执行

    # server_fileobj = socket(AF_INET, SOCK_STREAM)
    # server_fileobj.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1)
    # server_fileobj.bind((‘127.0.0.1‘, 8080))
    # server_fileobj.listen(5)
    # server_fileobj.setblocking(False)
    # sel.register(server_fileobj, selectors.EVENT_READ, accept)

    while True:
        events = sel.select()   # 检测到所有的fileobj(监听列表中的所有对象,都是文件描述符),是否有完成wait data阶段。当监听到有事件时返回
        for sel_obj, mask in events:
            callback = sel_obj.data     # 第一次是callback = accpet  通过sel_obj.data就能拿到刚刚这个被监听对象的回调函数
            callback(sel_obj.fileobj, mask) # 第一次是ccpet(server_fileobj, 1)   直接调用回调函数

  客户端

import socket
from threading import Thread

def func():
    sk = socket.socket()
    sk.connect((‘127.0.0.1‘, 8080))
    sk.send(b‘hello‘)
    sk.close()

if __name__ == ‘__main__‘:
    for i in range(20):
        Thread(target=func).start()

  4.信号驱动IO

  5.异步IO

 6.五种IO模型的比较,个人觉得肯定还是异步IO好

原文地址:https://www.cnblogs.com/whylinux/p/9867149.html

时间: 2024-10-13 22:46:26

说说基于网络的五种IO模型的相关文章

聊聊 Linux 中的五种 IO 模型

本文转载自: http://mp.weixin.qq.com/s?__biz=MzAxODI5ODMwOA==&mid=2666538919&idx=1&sn=6013c451b5f14bf809aec77dd5df6cff&scene=21#wechat_redirect 上一篇<聊聊同步.异步.阻塞与非阻塞>已经通俗的讲解了,要理解同步.异步.阻塞与非阻塞重要的两个概念点了,没有看过的,建议先看这篇博文理解这两个概念点.在认知上,建立统一的模型.这样,大家在

Linux五种IO模型

Linux五种IO模型 转载:http://blog.csdn.net/jay900323/article/details/18141217 Linux五种IO模型性能分析 目录(?)[-] 概念理解 Linux下的五种IO模型 阻塞IO模型 非阻塞IO模型 IO复用模型 信号驱动IO 异步IO模型 个IO模型的比较 selectpollepoll简介 1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式:

Windows五种IO模型性能分析和Linux五种IO模型性能分析

Windows五种IO模型性能分析和Linux五种IO模型性能分析 http://blog.csdn.net/jay900323/article/details/18141217 http://blog.csdn.net/jay900323/article/details/18140847 重叠I/O模型的另外几个优点在于,微软针对重叠I/O模型提供了一些特有的扩展函数.当使用重叠I/O模型时,可以选择使用不同的完成通知方式. 采用事件对象通知的重叠I/O模型是不可伸缩的,因为针对发出WSAWa

[转载] Linux五种IO模型

转载:http://blog.csdn.net/jay900323/article/details/18141217 Linux五种IO模型性能分析 目录(?)[-] 概念理解 Linux下的五种IO模型 阻塞IO模型 非阻塞IO模型 IO复用模型 信号驱动IO 异步IO模型 个IO模型的比较 selectpollepoll简介 1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式:同步:      所谓同步

(转载) Linux五种IO模型

转载:http://blog.csdn.net/jay900323/article/details/18141217 Linux五种IO模型及分析 目录(?)[-] 概念理解 Linux下的五种IO模型 阻塞IO模型 非阻塞IO模型 IO复用模型 信号驱动IO 异步IO模型 个IO模型的比较 selectpollepoll简介 1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式:同步:      所谓同步,

聊聊Linux 五种IO模型

1 概念说明 在进行解释之前,首先要说明几个概念: 用户空间和内核空间 进程切换 进程的阻塞 文件描述符 缓存 IO 1.1 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方).操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限.为了保证用户进程不能直接操作内核(kernel),保证内核的安全,操作系统将虚拟空间划分为两部分,一部分为内核空间,一部分为用户空间.针对li

五种IO模型

首先说一下内核空间和用户空间,操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限.为了保证用户进程不能直接操作kernel,保证内核的安全,操作系统将虚拟空间划分为两部分,一部分为内核空间,一部分为用户空间.针对linux操作系统而言,将最高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF),供内核使用,称为内核空间,而将较低的3G字节(从虚拟地址0x00000000到0xBFFFFFFF),供各个进程使用,称为用户空间. 五种I

Linux五种IO模型(同步 阻塞概念)

Linux五种IO模型 同步和异步 这两个概念与消息的通知机制有关. 同步 所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回.比如,调用readfrom系统调用时,必须等待IO操作完成才返回. 异步 异步的概念和同步相对.当一个异步过程调用发出后,调用者不能立刻得到结果.实际处理这个调用的部件在完成后,通过状态.通知和回调来通知调用者.比如:调用aio_read系统调用时,不必等IO操作完成就直接返回,调用结果通过信号来通知调用者. 阻塞与非阻塞 阻塞与非阻塞与等待消息通知

Linux下的五种IO模型

5种IO模型 Linux下五种IO模型 (1)阻塞I/O:什么都不干,导致应用程序阻塞,等待数据准备好,如果数据没有准备好,一直阻塞,等数据准备好了从内核拷贝到用户空间 (2)非阻塞I/O:把一个套接字接口设置为非阻塞,告诉内核,当所请求的IO无法完成时,不要将进程睡眠,而是返回一个错误,这样IO操作函数会不断地测试数据是否准备好,如果没有准备好 ,继续测试,直到准备好为止 (3)I/O复用(select epoll):select或epoll会使进程阻塞,但是和阻塞IO不同的是,这两个函数可以