linux下的io模型

1、用户态和内核态

因为操作系统的资源是有限的,如果访问资源的操作过多,必然会消耗过多的资源,而且如果不对这些操作加以区分,很可能造成资源访问的冲突。所以,为了减少有限资源的访问和使用冲突,Unix/Linux的设计哲学之一就是:对不同的操作赋予不同的执行等级,就是所谓特权的概念。简单说就是有多大能力做多大的事,与系统相关的一些特别关键的操作必须由最高特权的程序来完成。Intel的X86架构的CPU提供了0到3四个特权级,数字越小,特权越高,Linux操作系统中主要采用了0和3两个特权级,分别对应的就是内核态和用户态。运行于用户态的进程可以执行的操作和访问的资源都会受到极大的限制,而运行在内核态的进程则可以执行任何操作并且在资源的使用上没有限制。很多程序开始时运行于用户态,但在执行的过程中,一些操作需要在内核权限下才能执行,这就涉及到一个从用户态切换到内核态的过程

用户态和内核态的转换

a、系统调用

系统调用的本质其实也是中断,相对于外围设备的硬中断,这种中断称为软中断

b、异常

当CPU正在执行运行在用户态的程序时,突然发生某些预先不可知的异常事件,这个时候就会触发从当前用户态执行的进程转向内核态执行相关的异常事件,典型的如缺页异常。

c、外围设备的中断

当外围设备完成用户的请求操作后,会像CPU发出中断信号,此时,CPU就会暂停执行下一条即将要执行的指令,转而去执行中断信号对应的处理程序,如果先前执行的指令是在用户态下,则自然就发生从用户态到内核态的转换

总结:

内核态可以访问受保护的内存空间,也有访问底层硬件设备的所有权限。为了保证用户进程不能直接操作内核(kernel),保证内核的安全,操心系统将虚拟空间划分为两部分,一部分为内核空间,一部分为用户空间。

2、同步和异步的区别

同步io需要主动读写数据,在读写过程中会阻塞,异步io只需要读写完成的通知,读写操作由内核态完成

3、关于异步阻塞和异步非阻塞

异步阻塞,用户进程(线程)发起读写操作,在原地等待内核态返回读写完成的结果。此时阻塞整个进程

异步非阻塞,用户进程发起读写操作后,不在原地的等待内核态完成读写操作的结果。可以先去干点别的事

4、同步的几种io模型

以read为例

1、同步阻塞

1、进程发起read,进行recvfrom系统调用;

2、内核态准备数据

3、同时进程阻塞

4、阻塞直到数据从内核态copy到用户态,内核返回结果,进程解除阻塞。

总结:准备数据和数据copy两个阶段都阻塞。

2、同步非阻塞

1、进程发起read操作,内核数据没有准备好,立刻返回一个error.

2、用户进程收到error,知道数据没有准备好,于是再次发起read操作,直到数据准备好。

3、用户进程收到数据准备好的信号,发送system call,copy数据,此时进程开始阻塞

4、数据copy完成,返回给用户进程解除阻塞。

总结:数据准备阶段,用户进程不断询问内核数据准备好了没,数据copy阶段进程阻塞

3、io多路复用

1、用户进程调用select,进程阻塞,同时内核会监听所有select负责的socket.

2、当任何一个socket的数据准备好,select就会返回。

3、用户进程调用read操作,将数据从内核copy到用户进程。

总结:I/O 多路复用的特点是通过一种机制一个进程能同时等待多个文件描述符,而这些文件描述符(套接字描述符)其中的任意一个进入读就绪状态,select()函数就可以返回

如果处理的连接数不是很高的话,使用select/epoll的web server不一定比使用多线程 + 阻塞 IO的web server性能更好,可能延迟还更大。select/epoll的优势并不是对于单个连接能处理得更快,而是在于能处理更多的连接。

select、poll、epoll的区别:

select 是不断轮询去监听的socket,socket个数有限制,一般为1024个;

poll还是采用轮询方式去监听,只不过没有个数限制。

epoll并不用采用轮询方式去监听,而是当socket有变化时通过回调方式主动告知用户进程。

select支持多平台,epoll只支持linux平台。

select实现ftp

import select
import socket

server = socket.socket()
server.bind((‘127.0.0.1‘, 9991))
server.listen(10)
server.setblocking(False)

r_list = [server, ]
w_list = []
w_data = {}

while True:
    rl, wl, xl = select.select(r_list, w_list, [], 0.5)
    print(wl)
    for sock in rl:
        if sock == server:
                conn, addr = server.accept()
                r_list.append(conn)
        else:
            try:
                data = sock.recv(1024).decode()
                if not data:
                    sock.close()
                    r_list.remove(sock)
                    continue
                w_list.append(sock)
                w_data[sock] = data.upper().encode()

            except Exception as e:
                print(e)
                sock.close()
                r_list.remove(sock)

selectors实现ftp

import selectors
import socket

def accept(obj, mask):
    conn,addr = obj.accept()
    sel.register(conn, selectors.EVENT_READ, read)

def read(obj,mask):

    try:
        data = obj.recv(1024).decode()
        if not data:
            sel.unregister(obj)
            obj.close()
            return
        print(data)
        obj.send(data.upper().encode())
    except Exception as e:
        print(e)
        obj.close()
        sel.unregister(obj)

server = socket.socket()
server.bind((‘127.0.0.1‘, 9990))
server.listen(10)
server.setblocking(False)
sel = selectors.DefaultSelector()
sel.register(server, selectors.EVENT_READ, accept)
while True:
    events = sel.select()
    for obj, mask in events:
        callback = obj.data
        callback(obj.fileobj, mask)

大量参考:

http://www.cnblogs.com/zingp/p/6863170.html

https://www.cnblogs.com/bakari/p/5520860.html

原文地址:https://www.cnblogs.com/Jason-lin/p/8723743.html

时间: 2024-10-12 19:31:54

linux下的io模型的相关文章

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 的 Socket IO 模型

前言 之前有看到用很幽默的方式讲解Windows的socket IO模型,借用这个故事,讲解下linux的socket IO模型: 老陈有一个在外地工作的女儿,不能经常回来,老陈和她通过信件联系. 他们的信会被邮递员投递到他们小区门口的收发室里.这和Socket模型非常类似. 下面就以老陈接收信件为例讲解linux的 Socket I/O模型. 一.同步阻塞模型 老陈的女儿第一次去外地工作,送走她之后,老陈非常的挂心她安全到达没有:于是老陈什么也不干,一直在小区门口收发室里等着她女儿的报平安的信

[转载] 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模型(同步 阻塞概念)

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

Linux 下网络 IO 的多路复用

2019-10-20 关键字:select 与 poll 在 Linux 系统下,IO 总共可以分为以下四种: 1.阻塞 IO: 2.非阻塞 IO: 3.IO多路复用: 允许同时对多个 IO 进行控制. 4.信号驱动 IO: 一种异步通信模型.前面三种 IO 都是同步型的,唯这一种是异步型的. 阻塞 IO 所谓阻塞 IO 就是在调用相关函数时,程序的运行指针会暂停往下执行,直至这个 IO 操作有结果返回为止.简单来说就是我发起一个 IO 操作请求,你有数据就返回给我,没数据我就等你到有数据为止.

Linux 环境下 网络IO模型

本文讨论的背景是Linux环境下的network IO. IO发生时涉及的对象和步骤: 对于一个network IO (这里我们以read举例),它会涉及到两个系统对象,一个是调用这个IO的process (or thread),另一个就是系统内核(kernel).当一个read操作发生时,它会等待内核经历两个阶段: 1  内核数据准备 (Waiting for the data to be ready) 2  内核把数据从内核空间,拷贝到用户空间中 (Copying the data from

Linux五种IO模型性能分析

socket阻塞与非阻塞,同步与异步 作者:huangguisu 1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式:同步:      所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回.也就是必须一件一件事做,等前一件做完了才能做下一件事. 例如普通B/S模式(同步):提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事 异步:      异步的概念和同步相对