驱动 5.23

1.阻塞io

        阻塞式IO在进行数据读取时,如果内核中没有数据(发送端可能还没有发送数据或者发送的数据还没有达到),此时内核就开始等待数据,同时用户进程也进入阻塞状态,整个进程就会被挂起等待,不能做其他的事情。当有数据到达内核时,内核等待结束,将数据从内核拷贝到用户区,用户进程结束阻塞,从挂起状态转为运行状态。

        在Linux中,默认所有的socket都是阻塞式的。阻塞式接口是指当进行系统调用时,如果数据没有准备好,该应用进程就会被挂起,系统调用不会返回,直到有数据达到或者调用出错时,系统调用才会返回,进程才会结束阻塞状态。

2.非阻塞io

        非阻塞式IO在使用recvfrom等系统调用进行数据读取时,如果内核中没有数据到达,此时内核会进行等待。但是与阻塞式IO不同的是,此时的用户进程并不会被阻塞,不会被挂起,而是出错返回。

  但是之后内核将数据准备好之后,由于该系统调用已经返回,所以进程无法得到数据已经准备好并且无法将数据由内核拷贝到用户区。所以,此时还需要使用系统调用进行数据的拷贝。因为不知道内核什么时候将数据准备好,所以就需要不断的使用系统调用来询问内核有没有将数据准备好,一旦准备好就进行数据的拷贝。

  非阻塞式IO中,一般需要循环的对文件描述符进行读写,不断的询问数据有没有准备好。这个过程就称为轮询。因此,在非阻塞IO中,内核在等待数据,用户进程在轮询访问数据有无准备好。

3.io多路复用

        IO多路复用下,进程首先使用select/epoll等系统调用等待多个连接。select等系统调用可以设置阻塞和非阻塞(或者阻塞的时间)。如果是阻塞方式,若等待的所有连接的数据均未达到,此时进程会阻塞在select处。当至少有一个连接就绪条件满足时,该系统调用就会返回,然后应用进程再调用read等分别对就绪的连接进行数据的拷贝。如果是非阻塞方式或者设置了阻塞的时间,当没有调用select时或者在规定时间内没有连接满足就绪条件,此时select会出错返回-1,此时为了对数据进行操作,所以必须循环的调用select来判断有无连接满足就绪条件。

  当等待的多个连接中至少有一个满足就绪条件时,select返回数据准备好的连接。此时应用进程调用read(此时的套接字是阻塞的)等对数据进行拷贝。此时,read一定不会阻塞。因为内核中一定有数据到达。

阻塞io和非阻塞io

共同点

  数据从内核拷贝到应用进程其实还是阻塞的状态

不同点

  阻塞IO需要一直等待内核数据准备好,进程处于阻塞状态;非阻塞IO一直在询问内核数据是否准备好,进程处于运行态,一直占用着CPU

非阻塞IO和IO多路复用

共同点

  数据从内核拷贝到应用进程其实还是阻塞的状态

不同点

  当有多个连接的时候,非阻塞IO会不断地询问每个连接的数据是否准备好,如果准备好则调用read系统调用进行读取,但是我们上面说过,如果连接一直没有数据到,将会有许多无用的轮旋;IO多路复用则把这项工作交给操作系统,有操作系统通过与IO设备绑定的回调直接把有数据到来的连接返回给应用进程,应用进程可以直接一个个读取而无需再像非阻塞IO那样去询问没有数据的连接。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值