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的更多相关文章

  1. Linux设备驱动程序学习 高级字符驱动程序操作[阻塞型I/O和非阻塞I/O]【转】

    转自:http://blog.csdn.net/jacobywu/article/details/7475432 阻塞型I/O和非阻塞I/O 阻塞:休眠 非阻塞:异步通知 一 休眠 安全地进入休眠的两 ...

  2. C#学习笔记之线程 - 高级主题:非阻塞同步

    非阻塞同步 - Nonblock Synchronization 前面提到,即使在简单的赋值和增加一个字段的情况下也需要处理同步.尽管,使用锁可以完成这个功能,但是锁必定会阻塞线程,需要线程切换,在高 ...

  3. UNIX环境高级编程——非阻塞设置

    非阻塞I/O使我们可以调用open.read和write这样的I/O操作,并使这些操作不会永远阻塞.如果这种操作不能完成, 则调用立即出错返回,表示该操作如继续执行将阻塞. 对于一个给定的描述符有两种 ...

  4. 【转载】高性能IO设计 & Java NIO & 同步/异步 阻塞/非阻塞 Reactor/Proactor

    开始准备看Java NIO的,这篇文章:http://xly1981.iteye.com/blog/1735862 里面提到了这篇文章 http://xmuzyq.iteye.com/blog/783 ...

  5. 网络IPC:套接字之非阻塞和异步I/O

    通常,recv函数没有数据可用时会阻塞等待.同样地,当套接字输出队列没有足够空间来发送消息时函数send会阻塞.在套接字非阻塞模式下,行为会改变.在这种情况下,这些函数不会阻塞而是失败,设置errno ...

  6. linux非阻塞的socket EAGAIN的错误处理

    http://blog.csdn.net/tianmohust/article/details/8691644 在Linux中使用非阻塞的socket的情形下. (一)发送时 当客户通过Socket提 ...

  7. Windows I/O模型、同步/异步、阻塞/非阻塞

    转载自:http://www.cppblog.com/tx7do/articles/5954.html 同步 所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回.按照这个定义,其实 ...

  8. 五种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          ...

  9. Android NIO(Noblocking I/O非阻塞I/O)小结

    参考:http://www.cnblogs.com/cpcpc/archive/2011/06/27/2123009.html 对于Android的网络通讯性能的提高,我们可以使用Java上高性能的N ...

随机推荐

  1. FOJ2022车站 线段树区间合并

    http://acm.fzu.edu.cn/problem.php?pid=2022 刚开始MLE,用map对应,果断爆内存了,然后改用去重,离散化, lowbound查找元素位置,速度还不错,不过p ...

  2. IOS UIView(UIButton)通过显示动画移动的时候 响应点击的解决方案

    今天在做一个UIButton显示动画的时候,遇到一个问题,就是在移动的时候 ,需要相应它的点击时间(click) 通过CAKeyframeAnimation 来移动UIButton的layer ,效果 ...

  3. net中前台javascript与后台c#函数相互调用

    问: 1.如何在JavaScript访问C#函数? 2.如何在JavaScript访问C#变量? 3.如何在C#中访问JavaScript的已有变量? 4.如何在C#中访问JavaScript函数? ...

  4. memcpy、memmove、memset及strcpy函数实现和理解

    memcpy.memmove.memset及strcpy函数实现和理解 关于memcpy memcpy是C和C++ 中的内存拷贝函数,在C中所需的头文件是#include<string.h> ...

  5. JQuery笔记:JQuery和JavaScript的联系与区别

    来源:http://www.ido321.com/1019.html ps:LZ觉得这个标题有点大了,超出了能力范围,不喜勿碰.目前只记录LZ能力范围内的,日后持续补充. 一.JQuery对象和DOM ...

  6. 圆内,求离圆心最远的整数点 hiho一下第111周 Farthest Point

    // 圆内,求离圆心最远的整数点 hiho一下第111周 Farthest Point // 思路:直接暴力绝对T // 先确定x范围,每个x范围内,离圆心最远的点一定是y轴两端的点.枚举x的范围,再 ...

  7. C++ 之高效使用STL ( STL 算法分类)

    http://blog.csdn.net/zhoukuo1981/article/details/3452118

  8. Navicat 远程连接SQL Server 2014 Express 报08001错误

    场景:Navicat 远程连接SQL Server 2014 Express 报08001错误,经查验防火墙端口1434,1433已经打开 过程:1. 一开始觉得是连接名称问题,使用IP地址或者主机名 ...

  9. android sdk manager 闪退 打不开问题

    android sdk manager 闪退 打不开问题 环境 win8系统 如果访问不了  dl-ssl.google.com 网址,在C:\Windows\System32\Drivers\etc ...

  10. 第二百七十七天 how can I 坚持

    开玩笑要有个度,哎,或许这就是缘分,很容易受别人影响吗? 中国人为什么会经常抱怨,不抱怨,挺好. 睡觉,红颜祸水,老婆是要能一起 生活的,不是失去,是上天在帮我,哈哈.