网络I/O管理---五种I/O模型

                                                                      网络I/O管理---五种I/O模型

    

    网络I/O会涉及到到三个系统对象:一个是用户空间调用 I/O的进程或者线程;一个是内核空间的内核系统;最后一个是IO device.

       

  

    整个请求过程为:

  1. 用户进程/线程发起请求;
  2. 内核接受到请求后,从I/O设备中获取数据到内核buffer中;
  3. 再将内核buffer中的数据copy_to_user到用户进程的地址空间;

 

在整个请求过程中,数据输入到内核buffer需要时间从内核buffer复制到进程也需要时间。因此根据这两段时间内等待方式的不同,I/O分为以下 5 种模式:

    (1)阻塞IO(blocking IO)

    (2)非阻塞IO(Non-blocking IO)

    (3)IO复用(IO mutiplexing)

    (4)信号驱动的IO(signal driven IO)

    (5)异步IO(asynchrnous IO)

 

一、阻塞IO(blocking IO)

    在linux中,默认情况下所有的socket都是 blocking,一个典型的读操作流程如下:    

    

    例如当用户进程调用了 read 系统调用, kernel 就开始了 IO操作的 准备数据阶段。对于网络 IO来说,很多时候数据在一开始还没到达(比如,还没收到一个完整的数据包),

这时候kernel就需要等待足够的数据到来。用户空间这边,整个用户进程处于阻塞状态。

    当kernel一直等待数据准备好了,kernel就会将数据从kernel缓存缓冲区拷贝到用户空间用户进程/线程缓冲区,然后kernel返回结果,用户进程才解除block状态,重新运行起来。

    

    网络编程接口中listen(), send(), recv()等接口都是阻塞的,例如下边简单的“一问一答”的服务器模型。   

 

 大部分的socket接口都是阻塞型的,所谓阻塞型接口是指系统调用(一般是IO接口)不返回调用结果并让当前线程一直阻塞,只有当该系统调用获取结果或者超时出错时,

才返回。实际上,除非特别指定,几乎所有的IO接口,包括socket接口,都是阻塞型的。阻塞IO给网络编程带来了一个很大的问题,例如调用send的同时,线程被阻塞,

在此期间,线程将无法执行任何运算或响应任何网络请求。

 

 一个简单的改进方案是在服务端使用多线程(或多进程)。多线程(或多进程)的目的是让每个连接都拥有独立的线程(或线程),这样任何一个连接的阻塞都不会影响

其他的连接。具体使用多线程还是多进程,并没有一个特定的模式。传统意义上,进程的开销要远远大于线程,所以如果需要同时为较多的客户端服务,则不推荐多进程;

如果单个服务执行体需要消耗较多的 CPU 资源,

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值