zoukankan      html  css  js  c++  java
  • Linux五大网络IO模型

    对于一个应用程序即一个操作系统进程来说,它既有内核空间(与其他进程共享),也有用户空间(进程私有),它们都是处于虚拟地址空间中。用户进程是无法访问内核空间的,它只能访问用户空间,通过用户空间去内核空间复制数据,然后进行处理

    1、阻塞io(同步io):

      发起请求就一直等待,直到数据返回。好比你去商场试衣间,里面有人,那你就一直在门外等着。(全程阻塞)

      

    2、非阻塞io(同步io)—NIO:

      不管有没有数据都返回,没有就隔一段时间再来请求,如此循环。好比你要喝水,水还没烧开,你就隔段时间去看一下饮水机,直到水烧开为止。(复制数据时阻塞)

      

      当用户进程发出read操作时,如果kernel(内核空间)中的数据还没有准备好,那么它并不会block用户进程,而是立刻返回一个error。从用户进程角度讲 ,它发起一个read操作后,并不需要等待,而是马上就得到了一个结果。用户进程判断结果是一个error时,它就知道数据还没有准备好,于是它可以再次发送read操作。一旦kernel中的数据准备好了,并且又再次收到了用户进程的system call,那么它马上就将数据拷贝到了用户内存(此时占用CPU阻塞),然后返回。

    3、多路复用io(同步io): 

      I/O是指网络I/O,多路指多个TCP连接(即socket或者channel),复用指复用一个或几个线程。意思说一个或一组线程处理多个连接。比如课堂上学生做完了作业就举手,老师就下去检查作业。(对一个IO端口,两次调用,两次返回,比阻塞IO并没有什么优越性;关键是能实现同时对多个IO端口进行监听,可以同时对多个读/写操作的IO函数进行轮询检测,直到有数据可读或可写时,才真正调用IO操作函数。) 阻塞在select、poll、epoll、数据复制

       

      它的基本原理就是select/epoll这个function会不断的轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程。

      当用户进程调用了select,那么整个进程会被block(阻塞),而同时,kernel(内核)会“监视”所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。这个时候用户进程再调用read操作,将数据从kernel拷贝到用户进程
        这个图和阻塞IO图其实并没有太大的不同,事实上还更差一些。因为这里需要使用两个系统调用(select和recvfrom),而blocking IO只调用了一个系统调用(recvfrom)。但是,用select的优势在于它可以同时处理多个connection。

    4、信号驱动io(同步io):

      事先发出一个请求,当有数据后会返回一个标识回调,这时你可以去请求数据(不是轮询请求,而是收到返回标识后请求)。好比银行排号,当叫到你的时候,你就可以去处理业务了(复制数据时阻塞)。

      

      信号驱动IO,调用sigaltion系统调用,当内核中IO数据就绪时以SIGIO信号通知请求进程,请求进程再把数据从内核读入到用户空间,这一步是阻塞的

    5、异步io:

      发出请求就返回,剩下的事情会异步自动完成,不需要做任何处理,当IO返回结果时,再通知CPU进行处理。好比有事秘书干,自己啥也不用管。  

      

      用户进程发起read操作之后,立刻就可以开始去做其它的事。而另一方面,从kernel的角度,当它受到一个asynchronous read之后,首先它会立刻返回,所以不会对用户进程产生任何block。然后,kernel会等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,kernel会给用户进程发送一个signal,告诉它read操作完成了。

    异步IO是真正非阻塞的,它不会对请求进程产生任何的阻塞,因为户进程不需要去检查IO操作的状态,也不需要主动的去拷贝数据,因此对高并发的网络服务器实现至关重要。

    总结:

    五种IO的模型:阻塞IO、非阻塞IO、多路复用IO、信号驱动IO和异步IO;前四种都是同步IO,在内核数据copy到用户空间时都是阻塞的。
    阻塞IO和非阻塞IO的区别在于第一步,发起IO请求是否会被阻塞,如果会那就是传统的阻塞IO,如果不会那就是非阻塞IO
    同步IO和异步IO的区别就在于第二个步骤是否阻塞,如果实际的IO读写阻塞请求进程,那么就是同步IO;如果不阻塞,而是操作系统帮你做完IO操作再将结果返回给你,那么就是异步IO。

      如果是请求进程主动拷贝内核数据到用户空间,就是阻塞IO;否则是异步IO

  • 相关阅读:
    共享纸巾更换主板代码分析 共享纸巾主板更换后的对接代码
    Python Django Ajax 传递列表数据
    Python Django migrate 报错解决办法
    Python 创建字典的多种方式
    Python 两个list合并成一个字典
    Python 正则 re.sub替换
    python Django Ajax基础
    Python Django 获取表单数据的三种方式
    python Django html 模板循环条件
    Python Django ORM 字段类型、参数、外键操作
  • 原文地址:https://www.cnblogs.com/pluto-yang/p/12547099.html
Copyright © 2011-2022 走看看