Chinaunix首页 | 论坛 | 博客
  • 博客访问: 145356
  • 博文数量: 69
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 595
  • 用 户 组: 普通用户
  • 注册时间: 2016-07-16 00:00
个人简介

宁可逆流而上与众不同,也不顺风顺水随波逐流

文章分类

全部博文(69)

文章存档

2020年(1)

2018年(9)

2017年(43)

2016年(16)

我的朋友

分类: C/C++

2017-03-19 17:30:31

系统调用分为两类:低速系统调用和其它系统调用。而低速系统调用可能使进程永远阻塞
 低速系统调用包括
         1:在读某些类型的文件(管道,终端设备及网络设备)时,如果数据并不存在则可能会使调用者永远阻塞。
         2:如果数据不能立即被上述同样类型的文件接受(由于在管道中无空间、网络流控制等),则写操作也会使调用者阻塞。
         3:在某种条件发生之前,打开某种类型的文件会被阻塞(例如打开一个终端设备可能需等到与之链接的调制解调器应答;又例如在没有其它进程已用读模式打开该FIFO时若以只写方式打开FIFO,也要等待。
         4:对已经加上强制性记录锁的文件进行读、写。
         5:某些ioctl操作
         6:某些进程间通信函数(看了进程间通信后尝试列举出是哪些进程间通信)
非阻塞I/O含义:非阻塞I/O使我们调用open,read,write这样的I/O操作,并使这些操作永远不会阻塞。如果这种操作不能完成,则立即出错返回,表示该操作继续执行将阻塞。
指定文件描述符非阻塞的方法
          如果调用open函数获取描述符,可指定O_NONBLOCK标志
          对于已打开的一个描述符,可调用fcntl函数,由该函数打开O_NONBLOCK文件状态标志(最好先获取文件状态标志,再在原来的基础上和O_NONBLOCK做或运算)

点击(此处)折叠或打开

  1. #include
  2. #include                        
  3. #include<errno.h>
  4. #include<fcntl.h>

  5.  char buf[500000];
  6.  int main(void)
  7.  {
  8.    int ntowrite,nwrite;
  9.    char*ptr;
  10.    ntowrite=read(STDIN_FILENO,buf,sizeof(buf));
  11.    fprintf(stderr,"read %d bytes\n",ntowrite);
  12.  
  13.    struct stat ino_buf;
  14.    int fl=-1;
  15.    if((fl=fcntl(STDOUT_FILENO,F_GETFL))==-1){
  16.      puts("get stdout stat failed");
  17.      return errno;
  18.    }
  19.    if(fcntl(STDOUT_FILENO,F_SETFL,fl|O_NONBLOCK)==-1){
  20.      puts("set file stat failed");
  21.      return errno;
  22.    }
  23.    ptr=buf;
  24.    while(ntowrite>0){
  25.      errno=0;
  26.      nwrite=write(STDOUT_FILENO,ptr,ntowrite);
  27.      fprintf(stderr,"nwrite=%d,errno=%d\n",nwrite,errno);
  28.  
  29.      if(nwrite>0){
  30.        ptr+=nwrite;
  31.        ntowrite-=nwrite;
  32.      }
  33.    }
  34.    if(fcntl(STDOUT_FILENO,F_SETFL,fl|~O_NONBLOCK)==-1){
  35.      puts("recover file stat failed");
  36.      return 1;
  37.    }
  38.    exit(0);
  39. }

我先用dd命令复制一个702559字节的文件,然后将它作为程序的标准输入,并把程序的标准输出重定向到文件,结果显示一次性write成功。第二次标准输入不变,标准输出重定向到终端,标准错误输出重定向到stderr.out文件,然后我们查看标准错误输出文件,问了节省空间,我只截取了一部分,可以看到并不是每次都调用成功的,与文章最上面低速系统调用第二项吻合,当调用可能阻塞时会立即出错返回。
阅读(537) | 评论(0) | 转发(0) |
0

上一篇:线程私有数据

下一篇:记录锁

给主人留下些什么吧!~~