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. UITextView 不左上角显示

    在Autolayout中 UITextView显示不左上角显示,修改如下 在viewDidLoad里面添加如下代码 if([[[UIDevice currentDevice] systemVersio ...

  2. T-SQL 常用语句学习

    一.基础 1.说明:创建数据库 CREATE DATABASE database-name 2.说明:删除数据库 drop database dbname 3.说明:备份sql server ---  ...

  3. IOS-day02_OC中类的声明

    在上一个笔记中类的使用中,在编译链接的时候会有警告,原因就是我们没有对类进行声明 类的声明如下:使用关键字@interface #import <Foundation/Foundation.h& ...

  4. schema对象介绍

    1.schema对象简介 数据库schema为一组数据结构的逻辑集合,称之为schema对象,schema对象最贱的为表和索引,schema对象由SQL创建和维护. 一个数据库用户拥有一个用户名和各种 ...

  5. document.getElementsByClassName方法的重写(OVERRIDE)

    众所周知,对于IE8以下的浏览器(IE8居然是WIN7预装的)没有document.getElementsByClassName,网上也有很多重写的方法,以下是本人在项目中所使用的方法 documen ...

  6. Hard-Margin SVM(支持向量机)

    什么是Hard-Margin SVM?指的是这个向量机只适用于“数据完全可分(seperately)”的情况. (一)什么是支持向量机? 上述三条直线,选择哪一条比较好?直觉上来说,最右面的那条直线最 ...

  7. Java Client for Google Cloud Storage

    关于Google Cloud Storage Google Cloud Storage有益于大文件的存储与服务(serve).此外,Cloud Storage提供了对访问控制列表(ACLs)的使用,提 ...

  8. Windwos Server 2008: 当网卡有多个IP地址时,如何指定缺省地址?

    这实际是一个当应用向外发起连接时,协议栈对源IP地址的选择问题.如果你的应用没有显式绑定一个本地地址,协议栈会选择一个"最佳"的本地地址来使用. 从 Vista 之后这个选择策略发 ...

  9. numpy的矩阵运算

    矩阵赋值 >>> x1=np.arange(0,5) # array([0, 1, 2, 3, 4]) >>> x2=np.arange(1,6) # array( ...

  10. wine的中文字体显示

    从1.1.4开始wine的界面就已经支持中文了,但是对于软件中的中文支持并不太好,主要原因.还是字体...Let's go 首先,copy一下字体:把simsun.ttc (即宋体)复制到 ~/.wi ...