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模型是最常用的模型!
五种模型的对比图:
转载于:https://www.cnblogs.com/fangtaoa/p/9045851.html
Python高级网络编程系列之第二篇相关推荐
- Python高级网络编程系列之第一篇
在上一篇中我们简单的说了一下Python中网络编程的基础知识(相关API就不解释了),其中还有什么细节的知识点没有进行说明,如什么是TCP/IP协议有几种状态,什么是TCP三次握手,什么是TCP四次握 ...
- Python高级网络编程系列之基础篇
一.Socket简介 1.不同电脑上的进程如何通信? 进程间通信的首要问题是如何找到目标进程,也就是操作系统是如何唯一标识一个进程的! 在一台电脑上是只通过进程号PID,但在网络中是行不通的,因为每台 ...
- python高级网络编程_Python高级网络编程系列之基础篇
一.Socket简介 1.不同电脑上的进程如何通信? 进程间通信的首要问题是如何找到目标进程,也就是操作系统是如何唯一标识一个进程的! 在一台电脑上是只通过进程号PID,但在网络中是行不通的,因为每台 ...
- python高级网络编程_python高级编程——网络编程(二)
UDP 概念和介绍 UDP --- 用户数据报协议,是一个无连接的简单的面向数据报的运输层协议. UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并 不能保证它们能到达目的地. U ...
- Python Socket网络编程(二)局域网内和局域网与广域网的持续通信
目录 前言 IP地址 简介 公有IP 私有IP 局域网之间网络通信 前提 功能描述 源码 运行结果 局域网与广域网网络通信 前提 源码 结语 前言 本系列博客是笔者学习Python Socket的过程 ...
- Python Socket网络编程(一)初识Socket和Socket初步使用
目录 前言 网络编程 实质 IP地址和端口 数据传输协议 协议 Socket 概念 套接字 socket对象方法 初步使用 功能 源码 运行结果 结语 前言 本系列博客是笔者学习Python Sock ...
- CoreOS Fest 系列之第二篇: Systemd、Go、Calico、Sysdig
本文讲的是CoreOS Fest 系列之第二篇: Systemd.Go.Calico.Sysdig,[编者的话]在 CoreOS Fest 第二天的会议中,演讲者展示了多个开源项目和工具,包括 Sys ...
- 完毕port(CompletionPort)具体解释 - 手把手教你玩转网络编程系列之三
手把手叫你玩转网络编程系列之三 完毕port(Completion Port)具体解释 ...
- Python之网络编程(TCP套接字与UDP套接字)
文章目录 基于tcp的套接字 实现目标 tcp服务端源码 tcp客户端源码 tcp效果实现 基于udp的套接字 udp作用介绍 udp服务端源码 udp客户端源码 udp效果实现 用udp实现一个时间 ...
最新文章
- 黑客提交漏洞先获感谢后被举报 网络安全行业或现标志性事件
- Object-C 入门介绍
- lis3dh 三轴加速度计 运动检测 中断配置实现
- 自定义滚动条Js简版
- Linux ping不通百度的解决方法
- 第六十节,文本元素标签
- 摘要算法与加密(以MD5算法为例)
- ftp限流java,FTP流量限制的方法
- 流式数据分析_流式大数据分析
- 【LeetCode+51nod】股票低买高卖N题
- html给背景架渐变,JS和CSS实现渐变背景特效的代码
- C++算法学习(力扣:1003. 检查替换后的词是否有效)
- Javascript第二章中While/do..while循环第三课
- 工业和能源1994-2019年省级面板数据
- 使用Javascript 实现 分享到 新浪微博 QQ 空间等
- SQLServer2000数据库导入步骤
- 个人总结的新手看房买房注意事项,有遗漏的地方请各位同学帮忙补充
- 展讯7731C_M Android6.0 充电指示灯实现(一)------关机充电实现【转】
- Schedule(贪心,任务调度)
- oracle escape关键字用法