zoukankan      html  css  js  c++  java
  • Python高级网络编程系列之第二篇

      在上一篇中,我们深入探讨了TCP/IP协议的11种状态,理解这些状态对我们编写服务器的时候有很大的帮助,但一般写服务器都是使用C/Java语言,因为这些语言对高并发的支持特别好。我们写的这些简单的服务器主要是为了深入学习TCP/IP协议、IO操作以及Python中协程的原理。在上一篇中也提到非阻塞这个概念,在这一篇中,我们继续深入探讨IO模型,因为理解IO操作对我们深入学习异步编程有很大帮助。所以在这一节中我们主要是从Linux内核态和用户态的层面来考虑IO操作时会发生什么样的事情,Linux内核会做什么。

    一、常见5种IO模型

    1.阻塞IO模型

        阻塞IO模型图如下:

     

      说明:

      (1).当上层应用程序调用recv系统调用时,进程会从用户态切换到内核态;如果此时对方没有发送数据来(内核缓冲区没有数据),那么应用程序将会被阻塞(默认行为,被Linux内核阻塞)。

      (2).当对方把数据发送过来了之后,Linux内核会自动把数据copy到用户空间的缓冲区中,然后进程恢复执行,执行下一步操作!

    2.非阻塞IO模型

      非阻塞IO模型图如下:

      说明:

      (1). 进程中需要将套接字设置为非阻塞模式;

      (2). 进程会一直调用recv()函数去接收数据,如果缓冲区中没有数据,那么进程也不会被阻塞,只是recv()会返回一个错误码(EWOULDBLOCK)

      (3). 进程会不断轮询有没有数据到来。这样会造成进程忙等待。大量消耗CPU资源。因此很少使用,一般和select或epoll机制一起使用。

    3.IO复用模型

      IO复用模型图如下:

     

      说明:

      (1). 进程使用select机制(该机制由Linux内核支持,避免了进程忙等待),目的是去轮询文件描述符的状态变化

      (2). 当select管理的文件描述符没有变化时,进程也会被阻塞;但是使用select可以管理多个文件描述符,效率就提高了。这就不像非阻塞模型中,去轮询recv()。

      (3). select可以看成一个管家,使用select来管理多个IO。

        一旦检测到一个或多个IO有我们感兴趣的事件发生时,select函数将返回,返回值是检测到的事件个数。

      (4). select函数可以设置超时时间, 这样可以避免进程处于干等待状态,长期僵死

      (5). 和非阻塞IO模型相比,select IO复用模型相当于提前阻塞了。当有数据来到时,可以直接调用recv()来获取数据。

    4.信号驱动IO

      信号驱动IO模型图如下:

      说明:

      (1). 在上层应用程序中会建立SIGIO信号的处理程序。当缓冲区有数据来到时,内核会发送数据到上层应用程序。

      (2). 当上层应用程序收到信号后,调用recv()函数,因为缓冲区有数据,recv()函数一般不会被阻塞。

      (3). 这种模型用的比较少,属于典型的"拉模型",即,上层应用程序需要调用recv()函数把数据拉进来。

    5.异步IO模型

      异步IO模型图如下:

      说明:

      (1). 上层应用程序调用aio_read函数,同时会提交一个应用层的缓冲区给内核写入数据;调用完毕后,应用程序不会被阻塞,可以继续执行其他任务。

      (2). 当数据过来时,Linux内核主动把数据从内核空间copy到用户空间,然后再给应用程序发送一个信号,告诉进程数据已经复制过去了,你赶紧处理数据吧。

      (3). 这是一个"推模式",效率非常之高,应用程序有异步处理的能力(在Linux内核的辅助下,进程在处理其他任务的同时,也可以进行IO通讯)。与信号驱动IO模型相比,应用程序不需要调用recv()来接收数据!

      (4). 异步IO是什么?

        应用程序在处理其他事情的同时,还可以接收数据。

    小结:通过对比五种IO模型,我们可以很明显发现他们的区别以及效率,一般在开发中IO复用模型和异步IO模型是最常用的模型!

       五种模型的对比图:

       

  • 相关阅读:
    笨方法学python中执行argv提示ValueError: not enough values to unpack (expected 4, got 1)
    VMware workstation安装
    Redis bigkey分析
    MySQL drop table 影响及过程
    MySQL 大表硬连接删除
    ES elasticsearch 各种查询
    ES elasticsearch 各种聚合
    ES elasticsearch 聚合统计
    ES elasticsearch 实现 count单字段,分组取前多少位,以地理位置中心进行统计
    MySQL行溢出、varchar最多能存多少字符
  • 原文地址:https://www.cnblogs.com/fangtaoa/p/9045851.html
Copyright © 2011-2022 走看看