IO读写原理

为了避免用户进程直接操作内核,保证内核安全,操作系统将内存(虚拟内存)划分 
为两部分:

  1. 内核空间(Kernel-Space):内核模块运行在内核空间,对应的进程处于内核态;
  2. 用户空间(User-Space):用户程序运行在用户空间,对应的进程处于用户态。

     操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内核空间,也有访问底层硬件设备的权限。内核空间总是驻留在内存中,它是为操作系统的内核保留的。应用程序是不允许直接在内核空间区域进行读写,也是不容许直接调用内核代码定义的函数的。每个应用程序进程都有一个单独的用户空间,对应的进程处于用户态,用户态进程不能访问内核空间中的数据,也不能直接调用内核函数的,因此要进行系统调用的时候,就要将进程切换到内核态才能进行。

      内核态进程可以执行任意命令,调用系统的一切资源,而用户态进程只能执行简单的运算,不能直接调用系统资源,所以用户态进程必须通过系统接口(System Call),才能向内核发出指令,完成调用系统资源之类的操作。

      用户程序进行IO的读写,依赖于底层的IO读写,基本上会用到底层的两大系统调用: sys_read & sys_write。sys_read&sys_write两大系统调用都会涉及缓冲区。

  1. sys_read系统调用:把数据从内核缓冲区复制到应用程序的进程缓冲区
  2. sys_write系统调用:把数据从应用程序的进程缓冲区复制到操作系统内核缓冲区。

        应用程序的IO操作实际是内核缓冲区与应用程序进程缓冲区的缓冲复制sys_read&sys_write两大系统调用,都不负责数据在内核缓冲区和物理设备(如磁盘、网卡等)之间的交换。这项底层的读写交换操作,是由操作系统内核(Kernel)来完成的。

        所以,应用程序中的IO操作,无论是对Socket的IO操作,还是对文件的IO操作,都属于上层 
应用的开发,它们的在输入(Input)和输出(Output)维度上的执行流程,都是在内核缓冲区和进程缓冲区之间的进行数据交换。

内核缓冲区与进程缓冲区

        缓冲区的目的,是为了减少频繁地与设备之间的物理交换。计算机的外部物理设备与内存与CPU相比,有着非常大的差距,外部设备的直接读写,涉及操作系统的中断。发生系统中断时,需要保存之前的进程数据和状态等信息,而结束中断之后,还需要恢复之前的进程数据和状态等信息。为了减少底层系统的频繁中断所导致的时间损耗、性能损耗,于是出现了内核缓冲区。

        有了内核缓冲区,操作系统会对内核缓冲区进行监控,等待缓冲区达到一定数量的时候,再进行IO设备的中断处理,集中执行物理设备的实际IO操作,通过这种机制来提升系统的性能。至于具体在什么时候执行系统中断(包括读中断、写中断),则由操作系统的内核来决定,应用程序不需要关心。

        上层应用程序使用sys_read系统调用时,仅仅把数据从内核缓冲区复制到上层应用的缓冲区(进程缓冲区);上层应用使用sys_write系统调用时,仅仅把数据从应用的用户缓冲区复制到内核缓冲区中。

        内核缓冲区与应用缓冲区在数量上也不同,在Linux系统中,操作系统内核只有一个内核缓冲区。而每个用户程序(进程)则有自己独立的缓冲区,叫做用户缓冲区或者进程缓冲区。Linux系统中的用户程序的IO读写程序,在大多数情况下,并没有进行实际的IO操作,而是在用户缓冲区和内核缓冲区之间直接进行数据的交换。

        系统调用sys_read&sys_write,并不是使数据在内核缓冲区和物理设备之间的交换。 sys_read调用把数据从内核缓冲区复制到应用的用户缓冲区,sys_write调用把数据从应用的 
用户缓冲区复制到内核缓冲区,两个系统调用的大致的流程如下图所示:

举例说明,比如客户端和服务器端之间完成一次socket请求和响应(包括sys_read和sys_write)的数据交换 ,其流程如下:

  1. 客户端发送请求:客户端程序通过sys_write系统调用,将数据复制到内核缓冲区,Linux将内核缓冲区的请求数据通过客户端器的网卡发送出去。
  2. 服务端系统接收数据:在服务端,这份请求数据会被服务端操作系统通过DMA硬件,从接收网卡中读取到服务端机器的内核缓冲区。
  3. 服务端程序获取数据:服务端程序通过sys_read系统调用,从Linux内核缓冲区复制数据,复制到用户缓冲区。
  4. 服务器端业务处理:服务器在自己的用户空间中,完成客户端的请求所对应的业 
    务处理。
  5. 服务器端返回数据:服务器程序完成处理后,构建好的响应数据,将这些数据从用户缓冲区写入内核缓冲区,这里用到的是sys_write系统调用,操作系统会负责将内核缓冲区的数据发送出去。
  6. 服务端系统发送数据:服务端Linux系统将内核缓冲区中的数据写入网卡,网卡通过底层的通信协议,会将数据发送给目标客户端。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值