文章目录

  • 1. 基本概念
    • 1.1 阻塞与非阻塞
    • 1.2 同步与异步
    • 1.3 为什么没有“异步阻塞”
  • 2. 五种IO模型
    • 2.1 阻塞 blocking
    • 2.2 非阻塞 non-blocking
    • 2.3. IO复用(IO multiplexing)
    • 2.4 信号驱动(signal-driven)
    • 2.5 异步(asynchronous)

1. 基本概念

首先回顾并理解一下网络IO中阻塞、非阻塞;同步、异步的概念。

首先我们要知道:一个典型的网络IO接口调用,分为两个阶段,分别是“数据就绪”和“数据读写”。
阻塞与非阻塞是“数据就绪”阶段的概念,同步与异步是“数据读写”阶段的概念。

1.1 阻塞与非阻塞

所谓阻塞,就是IO在没有准备好数据的时候,调用IO方法的线程会被阻塞,直至收到数据时解除阻塞;而非阻塞IO在没有准备好数据的时候IO方法一样会返回,线程不会被阻塞。以recv方法为例,我们一般这样调用:

int size = recv(sockfd, buf, 1024, 0);

我们创建的sockfd默认是阻塞的,那么当执行这个函数时,如果sockfd对应的socket上数据没有就绪(即TCP接收缓存区中无数据),则该线程会阻塞,再往下的代码不会执行;但如果我们使用fcntl设置sockfd对应的socket为非阻塞,该socket工作在非阻塞状态下,那么执行该函数时,无论是否有数据准备好,该函数都会返回,然后我们可以通过返回的size值和errno来判断是否读到数据:

size == -1 && errno == EAGAIN: 表示没有读到数据,是因为非阻塞才返回;
size == 0:表示对端断开连接;
size > 0 : 表示读到数据,size为数据的长度;

1.2 同步与异步

再来说网络IO的同步和异步。刚才我们讨论阻塞和非阻塞时,关注的是数据准备阶段且数据没有准备好的情况,现在我们讨论同步和异步,关注的是数据已经准备好(TCP接收缓存区中有数据),进入数据读写阶段时的情况。

同步:同步表示A向B请求调用一个网络IO接口时,数据的读写都是由请求方A自己来完成的(不管是阻塞还是非阻塞)
比如调用recv方法(recv是同步IO方法)的时候其检测到数据已经准备好,然后把数据从内核的TCP接受缓存区拷贝到我们传入的buf(recv方法的第二个参数)中,这一拷贝过程耗费的是调用recv的线程的时间,直至拷贝结束,recv才返回;

异步:异步表示A向B请求调用一个网络IO接口时,向B传入请求的事件以及事件发生时通知的方式,A就可以处理其它逻辑了,当B监听到事件处理完成后,会用事先约定好的通知方式,通知A处理结果。
比如某个应用程序调用了一个异步IO的API来处理数据读入(如aio_read),那么应用程序只需把需要监听的sockfd给内核传入,内核来负责数据的准备和读入。在此期间,应用程序可以做自己的事情。数据读入完毕以后,再通过信号等方式来通知应用程序。

1.3 为什么没有“异步阻塞”

把阻塞、非阻塞,同步、异步两两组合有:

  • 同步阻塞
  • 同步非阻塞
  • 异步阻塞
  • 异步非阻塞

其中,所有平时使用的Linux网络IO的API都是同步的(如write、read、recv等等),我们可以通过设置其关注的socket为阻塞或者非阻塞,这样就有了同步阻塞和同步非阻塞的API。

但是异步的API一定是非阻塞的,因为异步IO是要让内核帮我们完成数据的读写,让调用它的应用程序可以去做自己的事情,如果异步的同时又阻塞,那么应用程序无法做自己的事情,异步就失去了意义。

2. 五种IO模型

有了以上的知识铺垫,再学习Linux的五种IO模型就通畅很多。

2.1 阻塞 blocking

调用者调用了某个函数,等待这个函数返回,期间什么也不做,不停的去检查这个函数有没有返回,必须等这个函数返回才能进行下一步动作。下图以read为例。

2.2 非阻塞 non-blocking

非阻塞等待,每隔一段时间就去检测IO事件是否就绪。没有就绪就可以做其他事。非阻塞I/O执行系统调用总是立即返回,不管事件是否已经发生,若事件没有发生,则返回-1,此时可以根据 errno 区分这两种情况,对于accept,recv 和 send,事件未发生时,errno 通常被设置成 EAGAIN。

2.3. IO复用(IO multiplexing)

Linux 用 select/poll/epoll 函数实现 IO 复用模型,这些函数也会使进程阻塞,但是和阻塞IO所不同的是这些函数可以同时阻塞多个IO操作。而且可以同时对多个读操作、写操作的IO函数进行检测。直到有数据可读或可写时,才真正调用IO操作函数。

2.4 信号驱动(signal-driven)

Linux 用套接口进行信号驱动 IO,安装一个信号处理函数,进程继续运行并不阻塞,当IO事件就绪,进程收到SIGIO 信号,然后处理 IO 事件。

注意区分信号驱动和异步IO的区别:信号驱动中,内核在数据准备阶段是异步,但在数据读写阶段是同步,仍然要花费应用程序自己的时间;与非阻塞IO的区别在于它提供了消息通知机制,不需要用户进程不断的轮询检查,减少了系统API的调用次数,提高了效率。

2.5 异步(asynchronous)

Linux中,可以调用 aio_read 函数告诉内核描述字缓冲区指针和缓冲区的大小、文件偏移及通知的方式,然后立即返回,当内核将数据拷贝到缓冲区后,再通知应用程序。从图中可以看出,异步IO是内核负责把数据从内核空间拷贝到用户空间,不耗费应用程序自己的时间,而前面四种IO方式在数据读写阶段都需要应用程序自己负责。

【Linux网络编程学习】阻塞、非阻塞、同步、异步以及五种I/O模型相关推荐

  1. 网络编程学习笔记(非阻塞accept)

    修改TCP回射客户程序,在跟服务器建立连接后发送一个RST.这种情况可以如下模拟: 一旦建立连接,设置SO_LINGER选项,把l_onoff标志置为1,l_linger时间置为0.在关闭连接时,TC ...

  2. 网络编程学习笔记(非阻塞connect)

    设置非阻塞,如果返回EINPROGRESS,表示正在建立连接,还没有完成 非阻塞的三个用途: 1.我们可以在三路握手的同时做其它的处理.connect要花一个往返时间完成,而且可以是在任何地主,从几个 ...

  3. 网络编程学习笔记(非阻塞读和写)

    维护两个缓冲区:to容纳从标准输入到服务器的数据,from容纳从服务器到标准输出的数据 toiptr指向从标准输入读入的数据可以存放的下一个字节,tooptr指下一个必须写入到套接口的字节.有(toi ...

  4. [Linux网络编程学习笔记]索引

    一.Linux基本知识 [学习笔记]Linux平台的文件I/O操作 [学习笔记]Linux平台的文件,目录及操作 [Linux学习笔记]标准输入输出 [Linux学习笔记]进程概念及控制 [Linux ...

  5. unix网络编程 str_cli epoll 非阻塞版本

    unix网络编程 str_cli epoll 非阻塞版本 unix网络编程str_cli使用epoll实现讲了使用epoll配合阻塞io来实现str_cli,这个版本是配合非阻塞io. 可以看到采用非 ...

  6. linux 网络编程学习

    linux 网络编程学习  Linux网络编程学习路线 - CTHON - 博客园 (cnblogs.com)

  7. 编程开发:Linux网络编程学习笔记

    非常全面.通俗易懂.值得借鉴的Linux网络编程学习笔记.关键字:linux linux编程 网络编程 linux网络编程 下载地址:点我下载 特别说明:本资源收集于网络,版权归原作者及版权商所有,仅 ...

  8. 网络编程 多道技术与同步/异步和阻塞/非阻塞

    UDP协议服务端模板代码 import socketserver = socket.socket(type=socket.SOCK_DGRAM) # 创建socket对象,括号内选择类型为UDPser ...

  9. Linux网络编程学习笔记(TCP)

    文章目录 1 字节序 1.1 定义 1.2 字节序转换函数 2 Socket地址 2.1 通用socket地址(实际开发不使用) 2.2 专用socket地址 2 IP地址转换 3 TCP通信流程 3 ...

最新文章

  1. 重读经典:完全解析特征学习大杀器ResNet
  2. hdu 2141 Can you find it?
  3. 2012年度IT博客大赛10强花落谁家暨圆满落幕
  4. 史上最全的并发编程学习
  5. Java中对字符串的操作
  6. UI登录表单使用模板素材
  7. c#使用Transactions类完成多个数据库的事务操作(分布式事务处理)
  8. HTML:页面布局和背景
  9. LeetCode刷题(简单)笔记C++
  10. GSM网络的网络架构,速来了解一下吧!
  11. 如何建立用户画像和用户体系?
  12. CSS - 选择器(标签选择器、类选择器、ID选择器)
  13. Python pyautogui 实现自动发送消息
  14. 美通企业日报 | 牛文文称明年创业要弯腰干脏活累活;高校百英里接力赛北大清华同济前三...
  15. 4.28dp专练总结
  16. 物联网应用入门--利用虚拟硬件模拟土壤湿度传感器应用编写
  17. 技术视频下载地址分享
  18. PHP后端生成签名后uniapp前端直传华为云OBS记录
  19. 小米AI魔法分身解密(一)
  20. ​也许还有 9 个月,我们就能见到 Apple Car 了

热门文章

  1. 创建一个自己的GitHub,创建自己的开源项目
  2. 我的osu游戏程序设计(oo)
  3. 在熟练使用2B铅笔前,请不要打开Axure
  4. (转)走进AngularJs(六) 服务
  5. 《测试驱动开发》读书笔记
  6. 分解 python_面试官:如何用Python实现将一个整数分解成质因数?
  7. python平均分由高到低顺序排列输出选手编号和最后得分_python 字典的使用案例二:求平均分,并按平均分由高到低输出选手编号和最后得分...
  8. 微型计算机接口与技术的交通灯,微机原理及接口技术课程设计交通灯
  9. ccs安装多版本编译器离线_大数据分析:学习工具JDK,在线安装指南
  10. go返回多个值和python返回多个值对比