多路IO复用与异步IO

  • 同步阻塞IO(BIO)与同步非阻塞IO(NIO)
    • 同步阻塞IO
    • 同步非阻塞IO
  • 多路IO复用
    • select()函数使用示例
      • 代码演示
    • poll()函数使用示例
      • 代码演示
  • 异步IO
    • 代码演示

什么时多路IO复用? 多路IO复用是一种同步IO模型,,它可以实现一个线程可以同时监视多个文件描述符,一旦有某个文件描述符准备就绪,就会通知应用程序,对该文件描述符进行操作。在监视的各个文件描述符没有准备就绪的时候,应用程序线程就会阻塞,交出cpu,让cpu去执行其他的任务,以此提高cpu的利用率。

同步阻塞IO(BIO)与同步非阻塞IO(NIO)

同步阻塞IO

关于同步阻塞IO可以打个比方就是我们要读取键盘和鼠标但是由于read()函数的阻塞作用导致我们只能读取按照程序编写的读取顺序来读取两个设备的数据,因为如果read()函数正在阻塞读取键盘数据,但是此时我们没有键盘输入,去动鼠标,鼠标就会返回数据,但是由于read()函数阻塞在了键盘读取上,所以我们就错过了读取鼠标数据的机会。

同步非阻塞IO

而同步非阻塞则是在一个while()循环里面使用设置了非阻塞的read()函数读取键盘和鼠标数据,如果没有读取到数据就会立即返回错误,然后继续读取鼠标和键盘,直到两个设备有数据来就会成功读取到数据。

多路IO复用

单线程使用select()/poll()等系统调用实现对多个文件句柄的监视,如果有某个文件句柄的事件发生就会返回,没有的话就会阻塞等待,单其实select()和poll()都是表现为外部阻塞式,内部非阻塞式自动轮询多路阻塞式IO。

select()函数使用示例

单个线程打开的FD是有限的,通常默认是1024个,可以通过FD_SETSIZE设置
每次调用select()都需要把fd集合从用户态拷贝到内核态,在需要轮询的fd很多时,会造成较大的性能开销。
select()前面提到了select()是通过轮询扫描检测事件有没有发生的所以执行效率比较低。

代码演示

在设置了select()函数的超时时间后,当函数超时后就会返回,后面再次执行到select()函数时,select()并不会阻塞了,不管有没有监视的文件句柄事件发生,select()函数都会返回超时结果。
也可应个select()的时间设置参数地址给NULL,这样select()函数就会不断地监视文件句柄。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>
int main(void)
{int fd=-2;char buf[20];fd_set set;struct timeval tm;bzero(buf,sizeof(buf));fd=open("/dev/input/mouse0",O_RDONLY);if (fd<0){perror("open:");}printf("already read\n");tm.tv_sec=10;   //设置等待超时时间tm.tv_usec=0;FD_ZERO(&set);   //清空set变量FD_SET(fd,&set); //将需要监视的fd加入到select()的见识列表FD_SET(0,&set);while (1){int ret=select(fd+1,&set, NULL,NULL, &tm);if (ret<0){perror("why");}else if (ret==0){printf("等待超时\n");}else{if(FD_ISSET(fd,&set)) //判断时哪一个被监视的文件句柄事件发生了{read(fd,buf,5);printf("read mouse0 buf=%s\n",buf);}if(FD_ISSET(0,&set)){read(0,buf,5);printf("read keyborad buf=%s\n",buf);}}}return 0;
}

poll()函数使用示例

poll()函数与select()函数一样每次调用都需要把fd集合从用户态拷贝到内核态,在需要轮询的fd很多时,会造成较大的性能开销。

poll()对文件句柄的监视也是和select()函数一样采用线性扫描的方式进行轮询,所以在高并发的情况下效率也是比较底下的。

但是poll()与select()不同的一点就是poll没有监视数量的限制

代码演示

在poll的使用过程中当程序开始运行等待超时后,如果发生IO事件后还能够检测到,但是当检测到IO事件和poll()就不会再超时了,就会一直等待监听事件的发生。这一点和select()有所不同,select()超时后就不在监听IO事件的发生了,而是一直返回超时。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>
#include <signal.h>
#include <poll.h>int main(void)
{int fd=-2;char buf[20];struct pollfd pfd[2]={0};  //监视两个文件句柄所以定义了一个结构体数组bzero(buf,sizeof(buf));fd=open("/dev/input/mouse0",O_RDONLY);if (fd<0){perror("open:");}printf("already read\n");pfd[0].fd=0;           //监视的文件描述符pfd[0].events=POLLIN;  //设置为监视读取事件pfd[1].fd=fd;pfd[1].events=POLLIN; while (1){int ret=poll(pfd,fd+1,1000);if (ret<0){perror("why");}else if (ret==0){printf("等待超时\n");}else{if(pfd[0].events==pfd[0].revents) //判断是否为监视的事件发生{bzero(buf,sizeof(buf));read(0,buf,5);printf("read keyboard data=%s\n",buf);}if (pfd[1].events==pfd[1].revents){bzero(buf,sizeof(buf));read(fd,buf,5);printf("read mouse data=%s\n",buf);}}}return 0;
}

异步IO

异步IO相当于系统内核为我们实现的一套软件中断程序,如下代码中的function()函数就可以比喻为中断服务函数。主程序在完成一些异步IO的初始化之后,在while()循环中检测键盘的输入,但是如果注册了异步事件的IO事件发生,就会去执行异步任务函数,即获取鼠标输入的数据。

代码演示

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
int fd=0;
void function(int sig)
{char buf[5]={0};if (sig!=SIGIO){return;}else{read(fd,buf,sizeof(buf));printf("read mouse data=%s\n",buf);}
}int main(void)
{char buf[20];int flag=-1;bzero(buf,sizeof(buf));fd=open("/dev/input/mouse0",O_RDONLY);if (fd<0){perror("open:");}printf("already read\n");//把鼠标的文件描述符设置为可以接收一部IOflag=fcntl(fd,F_GETFL);flag|=O_ASYNC;fcntl(fd,F_SETFL,flag);//把异步IO事件的接收进程设置为当前进程fcntl(fd,F_SETOWN,getpid());//注册当前进程的SINGIO信号捕获函数signal(SIGIO,function);while (1){memset(buf,0,sizeof(buf));read(0,buf,sizeof(buf));printf("read keynoard =%s\n",buf);}return 0;
}

多路IO复用与异步IO相关推荐

  1. IO复用在阻塞IO下的坑及解决

    一:引入 Unix/Linux上有五种IO模型:阻塞(blocking).非阻塞(non-blocking).IO复用(IO multiplexing).信号驱动(signal-driven).异步( ...

  2. linux支持异步io吗,Linux 异步IO

    io_submit.io_setup和io_getevents示例 [摘要:注:本宣布正在 io_submit.io_setup战io_getevents战LINUX上的AIO体系挪用.那有一个特别很 ...

  3. python 异步io 写excel_python异步IO编程(二)

    python异步IO编程(二) 目录 开门见山 Async IO设计模式 事件循环 asyncio 中的其他顶层函数 开门见山 下面我们用两个简单的例子来让你对异步IO有所了解 importasync ...

  4. 【免杀前置课——Windows编程】十四、异步IO——什么是异步IO、API定位问题、APC调用队列

    异步IO 异步IO 异步I/0注意事项: 定位问题 总解决方案 APC调用队列 异步IO 当我们读取一个文件时,一般情况下,线程是阻塞的,也就是说,当前线程在等待文件读取操作结束,这种方式叫同步IO. ...

  5. 聊聊对不同I/O模型的理解 (阻塞/非阻塞IO,同步/异步IO)

    一.关于I/O模型的问题 最近通过对ucore操作系统的学习,让我打开了操作系统内核这一黑盒子,与之前所学知识结合起来,解答了长久以来困扰我的关于I/O的一些问题. 1. 为什么redis能以单工作线 ...

  6. 五种IO模型:阻塞/非阻塞/复用/信号驱动/异步IO模型

    五种IO模型:阻塞/非阻塞/复用/信号驱动/异步IO模型 1. IO基本概念 1.1 IO概念 1.2 IO的两个阶段 1.2.1 IO的两个阶段-例子说明 1.2 IO种类 2. 五种IO模型 2. ...

  7. 【死磕NIO】— 阻塞IO,非阻塞IO,IO复用,信号驱动IO,异步IO,这你真的分的清楚吗?

    通过上篇文章([死磕NIO]- 阻塞.非阻塞.同步.异步,傻傻分不清楚),我想你应该能够区分了什么是阻塞.非阻塞.异步.非异步了,这篇文章我们来彻底弄清楚什么是阻塞IO,非阻塞IO,IO复用,信号驱动 ...

  8. IO:同步,异步,阻塞,非阻塞

    IO - 同步,异步,阻塞,非阻塞 都是老生常谈的东西,多通读几遍,理解透彻! 实际上同步与异步是针对应用程序与内核的交互而言的.同步过程中进程触发IO操作并等待(也就是我们说的阻塞)或者轮询的去查看 ...

  9. 5种网络IO模型:阻塞IO、非阻塞IO、异步IO、多路复用IO、信号驱动IO

    目录 前言 阻塞IO(blocking IO) 非阻塞IO(non-blocking IO) 多路复用IO(IO multiplexing) 异步IO(Asynchronous I/O) 模型间的区别 ...

  10. Node - 异步IO和事件循环

    前言 学习Node就绕不开异步IO, 异步IO又与事件循环息息相关, 而关于这一块一直没有仔细去了解整理过, 刚好最近在做项目的时候, 有了一些思考就记录了下来, 希望能尽量将这一块的知识整理清楚, ...

最新文章

  1. 如何和女生聊天不进入友谊区
  2. war3必须安装的游戏组件_在单独的WAR组件中对SPA资源和API实现进行分区
  3. OSPF Packet Details
  4. 【论文复现】Character-level Convolutional Networks for Text Classification
  5. miniUI mini-monthpicker ie8兼容性问题
  6. 字节跳动面试经验 php,双指针算法:字节跳动初级面试题 PHP
  7. 云计算机 公告,三星云停止服务公告: 给三星云用户的一封信
  8. 揭开Socket编程的面纱 (四)
  9. ListView刷新,图片闪烁问题
  10. 趋肤效应实验报告_GB/T 4857.2
  11. linux系统的系统命令大全,linux系统命令大全
  12. 实现OCR语言识别Demo(一)- BottomSheet实现
  13. 用思维导图和孩子们一起了解“什么是春节”
  14. Rime输入法之五笔自动上屏
  15. PortTunnel端口转发
  16. AITM 2-0003 水平燃烧试验
  17. faiss 三种基础索引方式
  18. 我给同事配的实用型的家庭多媒体影院系统 -- 3.音响选择篇
  19. 三国杀ol服务器维修中,三国杀OL登录不了
  20. SpringCloud Alibaba

热门文章

  1. ppt设置外观样式_PPT中设置视频外观样式的方法
  2. U盘加密软件测试简历,U盘加密软件哪个好用?2020U盘加密软件推荐
  3. 图书管理系统UML课程设计
  4. 职场新人如何高效办公?这10款软件帮到你!
  5. 教你怎么用爬虫程序采集企业信息及电话邮箱等信息(以企查查为例)
  6. Windows Xp下 无法定位程序输入点WSAPoll于动态链接库ws2_32.dll 的解决办法
  7. javascript 操作服务器 文件,使用javascript读取服务器文件
  8. 工业上服务器无线投屏到电视,台式电脑支持无线投屏吗 如何投屏到电视上
  9. 《银联提交服务单》-业务流程
  10. vcs与quartus联合仿真