概念篇——IO多路复用的机制

说明
  本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。
  QQ 群 号:513683159 【相互学习】
内容来源
  《Unix环境高级编程》

一、I/O多路复用的引出

不同的I/O使用情形:

情形一:一个输入(写),一个输出(读)

  常使用以下形式循环中使用阻塞I/O

while( (n = read(STDIN_FILENO,buf,BUFSIZE)) > 0 )
	if( write(STDOUT_FILENO,buf,n) != n )
		fprintf(stderr,"write error");
情形二:两个输入,两个输出

  两个输入中任一个都不能使用阻塞read(),因为我们永远不知道哪个输入有我们需要的数据。
  方案一
     描述fork()将一个进程变成两个进程,每个进程处理一条通路(执行阻塞read()
     产生问题:操作何时终止?
     解决问题:根据不同终止情形进行处理,如:使用信号机制。(使得程序复杂)
  方案二
    描述一个进程中的两个线程(执行阻塞I/O)
    避免终止的复杂度但要求处理线程之间的同步(使得程序复杂)。
  方案三
    描述一个进程中的两个线程(执行非阻塞I/O)
    缺点:浪费CPU时间。(在多任务系统中应该避免使用该方法)
  方案四
    描述使用异步I/O技术
    基本思想:进程告诉内核,当一个描述符已准备好可进行I/O时,用一个信号通知它。
    存在问题
      1.并非所有系统都支持该机制。
      2.这种信号对每个进程而言仅有一个起作用。(若两个都起作用则无法分辨)
  方案五
    描述使用I/O多路转接技术
    基本思想:先构造一张有关描述符的列表,然后调用一个函数,直到这些描述符中一个已准备好进行I/O时,该函数才返回,返回时,它告诉进程哪些描述符已准备好可进行I/O。
  

二、 I/O多路复用概念

1.I/O多路复用是什么?

  允许应用在多个文件描述符上同时阻塞,并在其中某个可读写时收到通知。
  (一个进程可监视多个文件描述符,若某文件描述符就绪,能通知程序进行相应的读写操作)

2.设计遵循的原则:

  ①当任何文件描述符指向的文件准备好输入输出时进行通知。
  ②在一个或更多文件描述符就绪前始终处于睡眠状态
  ③唤醒
  ④在不阻塞情况下处理所有I/O就绪的文件描述符
  ⑤回到①,循环

3.函数种类:

  ①select()函数
  ②poll()函数
  ③epoll()函数

三、函数简介

(1)函数简介:

详细请查看:函数简介篇——IO多路转接函数:select()/pselect()/poll()/ppoll()
  1️⃣select()/pselect()——同步I/O多路复用
    程序监视多个文件描述符,直到其中一个或多个文件描述符“就绪的”进行某种I/O操作
  2️⃣poll()/ppoll()——等待文件描述符上的某个事件
    等待一组文件描述符中的一个准备好执行I/O

(2)poll()与select()的优缺点

  poll()select()功能相同,但poll()系统调用仍然优于select().
1.poll()的优点:
    ①poll()无需使用者计算最大的文件描述符值加一和传递该参数。
    ②poll()在应对较大值的文件描述符时更具效率。

想像一下用select() 监视值为900的文件描述符——内核需要检查每个集合中的每个比特位,直到第九百个。

    ③ select()的文件描述符集合是静态大小的,所以要作出权衡:要么集合很小,限制了select()可以监视的文件描述符的最大值,要么较大,但是效率不高。尤其是当不能确定集合的组成是否稀疏时,对较大位掩码的操作效率不高。 使用poll()则可以创建合适大小的数组。只需要监视一项或仅仅传递一个结构体。

    ④若用select(),文件描述符集合会在返回时重新创建,这样的话之后每个调用都必须重新初始化它们。poll()系统调用分离了输入(events字段)和输出(revents字段),数组无需改变即而重用。
    ⑤select()timeout参数在返回时是未定义的。可移植的代码需要重新初始化它。然而pselect()没有这个问题。
2.select()的优点:
    ①poll()由于某些Unix系统不支持poll(),所以 select()的可移植性更好
    ②select()提供了更好的超时方案:直到微秒级。ppoll()pselect()在理论上都提供纳秒级的精度,但在实际中,没有任何调用可以可靠的提供哪怕是微秒级的精度。
    比poll()select()更好的是epoll接口,一个Linux特有的IO多路复用解决方案,我们将在第四章探讨。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值