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. 基于GPL329xx linux平台电容屏gsl1680的驱动调试分析

    因客户有用到了gsl1680 7寸电容屏,所以拿了一块过来,便在329xx的平台上面开始调试了. 大概浏览了一下所提供的资料,只有介绍模组的资料跟一份中文版的datasheet,datasheet只是 ...

  2. windows下安装和配置Weka

    Weka是一款免费的,非商业化的,基于java环境下的开源的机器学习以及数据挖掘软件.Weka里含有各种数据挖掘工具:数据预处理,分类与回归,聚类,关联规则和可视化工具. 一.安装weka 我们首先需 ...

  3. 如何学习java ee

    来看看Sun给出的J2EE 相关技术主要分为几大块. 1. Web Service技术 -  Java API for XML Processing (JAXP) -  Java API for XM ...

  4. 第二百五十一天 how can I 坚持

    hadoop,namenote和datanode.namenode如果要是在启动时加载到内存,会不会对内存的要求比较高呢. edits-->fsimage. secondnamenode,那么n ...

  5. ocp 1Z0-043 1-60题解析

    1.You observe that a database performance has degraded overa period of time. While investigating the ...

  6. HDU 5656 CA Loves GCD (数论DP)

    CA Loves GCD 题目链接: http://acm.hust.edu.cn/vjudge/contest/123316#problem/B Description CA is a fine c ...

  7. Azure 公网及内网ip绑定方法

    此文章为我的云服务绑定情况,仅供参考,适用于已经创建vm,但开始未绑定vip,后期进行vip的绑定,注意:绑定ip会造成虚拟机暂时离线. -Location(vm所在地) 注意区分 北部和东部: Ch ...

  8. 使用gson进行json转换

    Gson 是 Google 提供的用来在 Java 对象和 JSON 数据之间进行映射的 Java 类库.可以将一个 JSON 字符串转成一个 Java 对象,或者反过来. 示例代码如下: 实体定义 ...

  9. codeforces 630KIndivisibility(容斥原理)

    K. Indivisibility time limit per test 0.5 seconds memory limit per test 64 megabytes input standard ...

  10. PD16 Generate Datebase For Sql2008R2时报脚本错误“对象名sysproperties无效”

    PowerDesinger16创建数据库表到SQL2008R2时,执行报"对象名sysproperties无效"错误. 主要是在建模时我们对表.列增加了些说明注释,而Sql2005 ...