第十四章 高级IO

作者&投稿:邹利 (若有异议请与网页底部的电邮联系)
~

fd是阻塞还是非阻塞是可以设置的,这也直接影响系统调用函数是否阻塞还是非阻塞(直接返回错误)

对于一个给定的fd,有两种方法可以指定为非阻塞IO

任意多个进程在一个给定的字节上可以有一把共享的读锁,但是在一个给定字节上只能有一个进程有一把独占写锁

单进程加写锁,后面的锁范围会覆盖前面

F_SETLK 和 F_SETLKW 命令总是替换调用进程现有的锁(若已存在),所以调用进程决不会阻塞在自己持有的锁上,于是,F_GETLK 命令决不会报告调用进程自己持有的锁

前面已经给出了 open、fork 以及 dup 调用后的数据结构(见图 3-9 和图 8-2)

在原来的这些图上新加了 lockf 结构

建议性锁:就是内核不去维护这个锁,程序员自己要遵守这个原则

强制性锁会让内核检查每一个 open、read 和 write,验证调用进程是否违背了正在访问 的文件上的某一把锁。强制性锁有时也称为强迫方式锁

从一个fd读,然后写到另一个fd,不去设置O_NOBLOCK,就会是阻塞IO,很常见

telnet命令结构:从终端读(std-in),将数据写到网络连接上,同时从网络连接读,将所得数据写到终端上(std-out),在网络另一端,telnetd守护进程读用户的命令,发送给shell,将shell执行的结果通过telnet命令发送给用户,并显示在终端上,如同登入了远程机器了

telnet进程有两个输入,两个输出, 也就是两个fd要去读

终端用户写给telnet,网络连接返回给telnet;telnet输出给网络连接,telnet输出到终端给用户

Ps: 将两个输入描述符都设置为非阻塞的,对第一个描述符发一个 read。如果该输入上有数据,则 读数据并处理它。如果无数据可读,则该调用立即返回。然后对第二个描述符作同样的处理。在 此之后,等待一定的时间(可能是若干秒),然后再尝试从第一个描述符读。这种形式的循环称 为 轮询
这种方法的不足之处是浪费 CPU 时间。大多数时间实际上是无数据可读,因此执行 read 系统调用浪费了时间
在每次循环后要等多长时间再执行下一轮循环也很难确定
虽然轮询技术 在支持非阻塞 I/O 的所有系统上都可使用,但是在多任务系统中应当避免使用这种方法

tvptr就是等待的时间

readfds

fd0 fd1 fd2
0 0 0 ...

writefds

exceptfds

这三个可以通过下面宏来操作fd,如果是null,表示不关心

maxfdpl:最大fd编号+1,在 3 个描述符集中找出最大描述符编号值,然后加 1

或者可以设置为FD_SETSIZE,最大值,通常是1024,但是一般程序不会使用这么多fd,通常3-10个,这样内核就只需要在此范围内寻找打开的位

比如 readset 有fd(0),fd(3);write有fd(1),fd(2)

那么maxfdpl:4,也就是前四个位去寻找

maxfdp1一样

readfds,writefds,exceptfds一样

tsptr支持更加准确的时间,而且是const,pselect不能改变这个值

sigmask为了调用函数的时候可以安装这个参数的屏蔽字,返回的时候再回复以前的屏蔽字

类似select,但是接口不同

没有这个概念了:读,写,异常的fd集

pollfd:fd,感兴趣的事件,已经发生的事件

nfds unsigned long

poll没有修改events成员,与select不同,select修改参数来指示哪个fd已经准备好

与 select 一样,一个描述符是否阻塞不会影响 poll 是否阻塞。有超时设置,而且就算一个fd阻塞在那里,只要其他fd准备好了,依旧可以返回

select和poll实现了异步通知

关于描述符的状态,系统并 不主动告诉我们任何信息,我们需要进行查询(调用 select 或 poll)

而前面提到的缺点,信号不够,否则无法区分信号对应哪一个fd

SUSv4 中将通用的异步 I/O 机制从实时扩展部分调整到基本规范部分。这种机制解决了这些 陈旧的异步 I/O 设施存在的局限性。

POSIX异步IO接口会有问题

System V 的异步 I/O 信号是 SIGPOLL

异步 I/O 是信号 SIGIO 和 SIGURG 的组合

这些异步 I/O 接口使用 AIO 控制块来描述 I/O 操作

在进行异步 I/O 之前需要先初始化 AIO 控制块,调用 aio_read 函数来进行异步读操作,或 调用 aio_write 函数来进行异步写操作

要想强制所有等待中的异步操作不等待而写入持久化的存储中,可以设立一个 AIO 控制块并 调用 aio_fsync 函数

如果 op 参数设定为 O_DSYNC,那么操作执行起来就会像调用了 fdatasync 一样。否则,如果 op 参数设定为 O_SYNC, 那么操作执行起来就会像调用了 fsync 一样

像 aio_read 和 aio_write 函数一样,在安排了同步时,aio_fsync 操作返回。在异步 同步操作完成之前,数据不会被持久化。AIO 控制块控制我们如何被通知,就像 aio_read 和 aio_write 函数一样。为了获知一个异步读、写或者同步操作的完成状态,需要调用 aio_error 函数

执行 I/O 操作时,如果还有其他事务要处理而不想被 I/O 操作阻塞,就可以使用异步 I/O。然 而,如果在完成了所有事务时,还有异步操作未完成时,可以调用 aio_suspend 函数来阻塞进 程,直到操作完成。

list 参数是一个指向 AIO 控制块数组的指针,nent 参数表明了数组中的条目数。数组中的空 指针会被跳过,其他条目都必须指向已用于初始化异步 I/O 操作的 AIO 控制块

当还有我们不想再完成的等待中的异步 I/O 操作时,可以尝试使用 aio_cancel 函数来取消它们

还有一个函数也被包含在异步 I/O 接口当中,尽管它既能以同步的方式来使用,又能以异步的方 式来使用,这个函数就是 lio_listio。该函数提交一系列由一个 AIO 控制块列表描述的 I/O 请求

readv 和 writev 函数用于在一次函数调用中读、写多个非连续缓冲区。

散布读(scatter read)和聚集写(gather write)。

readn和writen

一次 read 操作所返回的数据可能少于所要求的数据,即使还没达到文件尾端也可能是 这样。这不是一个错误,应当继续读该设备

一次 write 操作的返回值也可能少于指定输出的字节数。这可能是由某个因素造成的, 例如,内核输出缓冲区变满

这两 个函数只是按需多次调用 read 和 write 直至读、写了 N 字节数据

存储映射 I/O(memory-mapped I/O)能将一个磁盘文件映射到存储空间中的一个缓冲区上, 于是,当从缓冲区中取数据时,就相当于读文件中的相应字节。与此类似,将数据存入缓冲区时, 相应字节就自动写入文件

存储映射 I/O 伴随虚拟存储系统已经用了很多年

为了使用这种功能,应首先告诉内核将一个给定的文件映射到一个存储区域中

新程序则不能通过 exec 继承存储映射区,调用 mprotect 可以更改一个现有映射的权限

如果共享映射中的页已修改,那么可以调用 msync 将该页冲洗到被映射的文件中。msync 函数类似于 fsync(见 3.13 节),但作用于存储映射区

当进程终止时,会自动解除存储映射区的映射,或者直接调用 munmap 函数也可以解除映射区。

关闭映射存储区时使用的文件描述符 并不解除映射区

对于 MAP_SHARED 区磁盘文件的更新,会在我们将数据写到存储映射区后的某个时刻, 按内核虚拟存储算法自动进行。在存储区解除映射后,对 MAP_PRIVATE 存储区的修改会被丢弃




加查县18313537629: core java 都包含哪些内容 -
姓楠盐酸: 第一章 Java的起源 第二章 Java语言概述 第三章 数据类型、变量、数组 第四章 运算符 第五章 程序控制语句 第六章 介绍类 第七章 进一步研究方法和类 第八章 继承 第九章 包和接口 第十章 异常处理 第十一章 多线程编程 第十二章 输入/输出、...

加查县18313537629: Java语言程序设计(第二版)第14章:多线程
姓楠盐酸: 第一个类extends Thread{public class Demo1 extends Thread{static int count=0;public void run(){for (int i = 2; i <= 100000; i++) {for (int j = i; j <= 100000; j++) {if(i%j==0){continue;}if(i==j){count++;System.out.println(i+"是第"+count+"个质素");}}}} } }

加查县18313537629: 阴阳师第十四章怎么过 剧情第14章打法及思路 -
姓楠盐酸: 首先猪的普攻,猪的普攻比大部分式神多了非常强力的辅助能力!虽然攻击力偏低,只能有攻击力的80%,但是却有20%的概率驱散对方的增益buff,最最关键的是所有增益buff!比如小鹿一堆增益buff说没就没OVO,然而最强的还是他的控制能力!20%概率沉睡!对于欧皇来说可以让你在睡梦中死亡.然后我们看看他的被动,攻击沉睡状态目标不会让他惊醒!没觉醒的时候已经可以让欧皇将你杀死于梦中!觉醒后的被动就更强了!还可以给队友增加续航能力!这也是剧情里四只猪的恶心能力之一然后就是他恶心的鬼火技能,群体沉睡!啊啊啊啊!我不要睡觉我要肝阴阳师!基础就有30%的概率而且还有效果命中的加成,简直让人醉生梦死.

加查县18313537629: 新约圣经马太福音第十四章的主题是什么? -
姓楠盐酸: 新约圣经马太福音第十四章的主题是:给五千人吃饱.

加查县18313537629: 马太福音第14章25 - 31节主要是什么意思 -
姓楠盐酸: 马太福音第14章25-31节主要的意思:到了晚上,因门徒遇风浪,耶稣便行走在海面上,为拯救他们.别人害怕,但彼得一听是主,就求主叫他从水面走去,可是因见风甚大就要沉下去,他就呼喊耶稣,耶稣赶紧伸手拉住他,并责备他的小信.这事教训我们不当随便求奇事、显异能,既有主的话,也不该看环境,怕风浪,因主总是有怜悯和体恤,什么时候呼求,他总是答应,绝不会让我们沉到海里去.大信可能变作小信,人自己是靠不住的,必须时时求主的扶持.主是全能的,超乎一切的势力,只仰望主就不会下沉.

加查县18313537629: DNF十四章大概什么内容
姓楠盐酸: 楼主您好!我向您保证DNF第十四章是开70级!以及全新高等级地图!时间就在6月中旬DNF三周年庆!欢迎采纳!祝您游戏愉快!

加查县18313537629: 火焰纹章死灵复生2,第十四章,神秘商店在哪 -
姓楠盐酸: 火焰纹章死灵复生2,第十四章,神秘商店在哪三个隐藏商店:贾哈那王宫,古拉德王宫,罗斯顿王宫 1,通关后,进入魔物退治自由模式,三个隐藏商店自动开启,只要带会员卡去地图上上述三地即可.2,流程中:贾哈那和古拉德的隐藏商店,都是位于地图左上方往下一点,有一条...神秘商店要会员卡,会员卡是雷纳多才持有的,在男主角路线的父与子和女主角的白沙之女皇这两章会出现,要用拉切尔说服他.特色系统 战棋游戏 战棋游戏,正式名称为策略角色扮演游戏(S.RPG),因为游戏中需要通过移动格子中..

加查县18313537629: dnf第十四章更新内容
姓楠盐酸: 应该会更新一套活动套装,以及全民宠物,还有时装镶嵌,时装打孔 可能会开几张新图,以及一些70之前的东西 70级是不会开的,腾讯还要捞点钱,70是最后的王牌,压箱底的东西不会这么快丢出来 新职业是男格斗吧,这个说不准,腾讯哪天心血来潮穿越也是有可能的

加查县18313537629: 《骆驼祥子》11到15章概括怎么写? -
姓楠盐酸: 第十一章老北平的祭社日子来临,祥子拉着曹先生回家的路上被侦探跟踪,曹先生躲进了左宅,而祥子躲藏的过程中却发现了侦探就是当年充军时认识的孙排长,孙排长接着机会要挟祥子,要他交出所有的积蓄保条命,祥子只得从命.茫茫大雪...

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网