高级I/O之非阻塞I/O
http://www.cnblogs.com/nufangrensheng/p/3515035.html中曾将系统调用分成“低速”系统调用和其他系统调用两类。低速系统调用是可能会使进程永远阻塞的一类系统调用,它们包括下列调用:
- 如果某些文件类型(例如管道、终端设备和网络设备)的数据并不存在,则读操作可能会使调用者永远阻塞。
- 如果数据不能立即被上述同样类型的文件接受(由于在管道中无空间、网络流控制等),则写操作也会使调用者永远阻塞。
- 在某种条件发生之前,打开某些类型的文件会被阻塞(例如打开一个终端设备可能需等到与之连接的调制解调器应答;又例如在没有其他进程已用读模式打开该FIFO时,若以只写模式打开FIFO,那么也要等待)。
- 对已经加上强制性记录锁的文件进行读、写。
- 某些ioctl操作。
- 某些进程间通信函数。
虽然读、写磁盘文件会使调用者在短暂时间内阻塞,但并不能将与磁盘I/O有关的系统调用视为“低速”。
非阻塞I/O使我们可以调用open、read和write这样的I/O操作,并使这些操作不会永远阻塞。如果这种操作不能完成,则调用立即出错返回,表示该操作如继续执行将阻塞。
对于一个给定的描述符有两种方法对其指定非阻塞I/O:
(1)如果调用open获得描述符,则可指定O_NONBLOCK标志(http://www.cnblogs.com/nufangrensheng/p/3497789.html)。
(2)对于已经打开的一个描述符,则可调用fcntl,由该函数打开O_NONBLOCK文件状态标志(http://www.cnblogs.com/nufangrensheng/p/3500350.html,其中,程序清单3-5中的函数可用来为一个描述符打开任一文件状态标志)。
系统V的早期版本使用标志O_NDELAY指定非阻塞方式。在这些版本中,如果无数据可读,则read返回值0。而UNIX系统又常将read返回值0解释为文件结束,两者有所混淆。因此POSIX.1提供了一个名字和语义都与O_NDELAY不同的非阻塞标志。确实,在系统V的早期版本中,当从read得到返回值0时,我们并不知道该调用是否阻塞了或已到文件结尾处。POSIX.1要求,对于一个非阻塞的描述符如果无数据可读,则read返回-1,并且errno被设置为EAGAIN。系统V派生的某些平台支持较老的O_NDELAY和POSIX.1的O_NONBLOCK两者。O_NDELAY只是为了向后兼容,不应在新应用程序中使用。
4.3BSD为fcntl提供了FNDELAY标志,其语义也稍有区别。它不只影响描述符的文件状态标志,还将终端设备或套接字的标志更改成非阻塞的,因此不仅影响共享同一文件表项的用户,而且对终端或套接字的所有用户其作用。另外,如果对一个非阻塞描述符的操作不能无阻塞地完成,那么4.3BSD返回EWOULDBLOCK。现今,基于BSD的系统提供POSIX.1的O_NONBLOCK标志,并且将EWOULDBLOCK定义为与POSIX.1的EAGAIN相同。这些系统提供与其他依从POSIX系统相一致的非阻塞语义。文件状态标志的更改影响同一文件表项的所有用户,但与通过其他文件表项对同一设备的访问无关(参加图3-1http://www.cnblogs.com/nufangrensheng/p/3498509.html和图3-3http://www.cnblogs.com/nufangrensheng/p/3498736.html)。
实例
程序清单14-1是一个非阻塞I/O的实例,它从标准输入读500 000字节,并试图将它们写到标准输出上。该程序先将标准输出设置为非阻塞的,然后用for循环进行输出,每次write调用的结果都在标准出错上打印。函数clr-fl类似于程序清单3-5(http://www.cnblogs.com/nufangrensheng/p/3500350.html)中的set_fl,但与set_fl的功能相反,它清除1个或多个标志位。
程序清单14-1 长的非阻塞write
- #include "apue.h"
- #include <errno.h>
- #include <fcntl.h>
- char buf[];
- extern void set_fl(int, int);
- extern void clr_fl(int, int);
- int
- main(void)
- {
- int ntowrite, nwrite;
- char *ptr;
- ntowrite = read(STDIN_FILENO, buf, sizeof(buf));
- fprintf(stderr, "read %d bytes\n", ntowrite);
- set_fl(STDOUT_FILENO, O_NONBLOCK); /* set nonblocking */
- ptr = buf;
- while(ntowrite > ) /* 这种形式的循环称为轮循,在多用户系统上它浪费了CPU时间。*/
- {
- errno = ;
- nwrite = write(STDOUT_FILENO, ptr, ntowrite);
- fprintf(stderr, "nwrite = %d, errno = %d\n", nwrite, errno);
- if(nwrite > )
- {
- ptr += nwrite;
- ntowrite -= nwrite;
- }
- }
- clr_fl(STDOUT_FILENO, O_NONBLOCK); /* clear nonblocking */
- exit();
- }
本篇博文内容摘自《UNIX环境高级编程》(第二版),仅作个人学习记录所用。关于本书可参考:http://www.apuebook.com/。
高级I/O之非阻塞I/O的更多相关文章
- Linux设备驱动程序学习 高级字符驱动程序操作[阻塞型I/O和非阻塞I/O]【转】
转自:http://blog.csdn.net/jacobywu/article/details/7475432 阻塞型I/O和非阻塞I/O 阻塞:休眠 非阻塞:异步通知 一 休眠 安全地进入休眠的两 ...
- C#学习笔记之线程 - 高级主题:非阻塞同步
非阻塞同步 - Nonblock Synchronization 前面提到,即使在简单的赋值和增加一个字段的情况下也需要处理同步.尽管,使用锁可以完成这个功能,但是锁必定会阻塞线程,需要线程切换,在高 ...
- UNIX环境高级编程——非阻塞设置
非阻塞I/O使我们可以调用open.read和write这样的I/O操作,并使这些操作不会永远阻塞.如果这种操作不能完成, 则调用立即出错返回,表示该操作如继续执行将阻塞. 对于一个给定的描述符有两种 ...
- 【转载】高性能IO设计 & Java NIO & 同步/异步 阻塞/非阻塞 Reactor/Proactor
开始准备看Java NIO的,这篇文章:http://xly1981.iteye.com/blog/1735862 里面提到了这篇文章 http://xmuzyq.iteye.com/blog/783 ...
- 网络IPC:套接字之非阻塞和异步I/O
通常,recv函数没有数据可用时会阻塞等待.同样地,当套接字输出队列没有足够空间来发送消息时函数send会阻塞.在套接字非阻塞模式下,行为会改变.在这种情况下,这些函数不会阻塞而是失败,设置errno ...
- linux非阻塞的socket EAGAIN的错误处理
http://blog.csdn.net/tianmohust/article/details/8691644 在Linux中使用非阻塞的socket的情形下. (一)发送时 当客户通过Socket提 ...
- Windows I/O模型、同步/异步、阻塞/非阻塞
转载自:http://www.cppblog.com/tx7do/articles/5954.html 同步 所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回.按照这个定义,其实 ...
- 五种I/O 模式——阻塞(默认IO模式),非阻塞(常用语管道),I/O多路复用(IO多路复用的应用场景),信号I/O,异步I/O
五种I/O 模式——阻塞(默认IO模式),非阻塞(常用语管道),I/O多路复用(IO多路复用的应用场景),信号I/O,异步I/O 五种I/O 模式:[1] 阻塞 I/O ...
- Android NIO(Noblocking I/O非阻塞I/O)小结
参考:http://www.cnblogs.com/cpcpc/archive/2011/06/27/2123009.html 对于Android的网络通讯性能的提高,我们可以使用Java上高性能的N ...
随机推荐
- 【LeetCode 209】Minimum Size Subarray Sum
Given an array of n positive integers and a positive integer s, find the minimal length of a subarra ...
- 解决虚拟机ssh连接出错connection refused
在安装操作系统之后,使用ssh连接,发现直接报错connection refused. 检查虚拟机的连接方式,在使用host only的方式的时候,必须接入网线,不然的网卡是不活动的,从而不能使用ss ...
- 关于javascript模式一书中var white = new Array(256).join(“ ”)
直接进入正题 var white = new Array(256).join(" ") 运行后,我们会发现white.length的长度是255,这个是为什么呢?书上没有给出解答, ...
- kendoui-在线文本编辑器
文本编辑器用过很多,fckeditor是我之前用的最多的,但是问题也有很多,诸如安全问题,浏览器兼容问题..所以最近也一直在找替代产品,正好在研究kendo,所以就尝试了下kendo提供的edit控件 ...
- Spark系列(七)Master中的资源调度
资源调度 说明: Application的调度算法有两种,分别为spreadOutApps和非spreadOutApps spreadOutApps 在spark-submit脚本中,可以指定要多少个 ...
- leetcode@ [336] Palindrome Pairs (HashMap)
https://leetcode.com/problems/palindrome-pairs/ Given a list of unique words. Find all pairs of dist ...
- java动态代理与老式AOP实现
JAVA的动态代理 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会 ...
- Spring EL Lists, Maps example
In this article, we show you how to use Spring EL to get value from Map and List. Actually, the way ...
- 怎样提交FIREDAC数据集的DELTA到中间件然后保存进数据库
你可以在客户端序列FireDAC数据集的DELTA , 将序列后的STREAM发送给中间件, 中间件的TFDQuery或TFDMemTable调用LOADFROMSTREAM()方法加载流, 然后调用 ...
- HDU 4463 Outlets (最小生成树)
题意:给定n个点坐标,并且两个点已经连接,但是其他的都没有连接,但是要找出一条最短的路走过所有的点,并且路线最短. 析:这个想仔细想想,就是应该是最小生成树,把所有两点都可以连接的当作边,然后按最小生 ...