《unix高级环境编程》高级 I/O——非阻塞 I/O

非阻塞 I/O 使我们可以调用 open、write 和 read 这样的 I/O 操作,并使这些操作不会永远阻塞。如果这种操作不能完成,则立即出错返回,表示该操作若继续执行将阻塞。
对于一个给定的文件描述符由以下两种方法可以对其指定非阻塞 I/O:
  1. 若调用 open 获得描述符,则可指定 O_NONBLOCK 标志;
  2. 对已打开的描述符,可以使用 fcntl,由该函数打开 O_NONBLOCK 文件状态标志;

测试程序:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include "apue.h"  
  2. #include <fcntl.h>  
  3.   
  4. void set_fl(int fd, int flags);  
  5. void clr_fl(int fd, int flags);  
  6.   
  7. char buf[500000];  
  8.   
  9. int main(void)  
  10. {  
  11.     int ntowrite, nwrite;  
  12.     char *ptr;  
  13.   
  14.     ntowrite = read(STDIN_FILENO, buf, sizeof(buf));  
  15.     fprintf(stderr, "read %d bytes.\n",ntowrite);  
  16.   
  17.     set_fl(STDOUT_FILENO, O_NONBLOCK);  
  18.   
  19.     ptr = buf;  
  20.     while(ntowrite > 0)  
  21.     {  
  22.         errno = 0;  
  23.         nwrite = write(STDOUT_FILENO, ptr, ntowrite);  
  24.         fprintf(stderr, "nwrite = %d, errno = %d\n", nwrite, errno);  
  25.   
  26.         if(nwrite > 0)  
  27.         {  
  28.             ptr += nwrite;  
  29.             ntowrite -= nwrite;  
  30.         }  
  31.     }  
  32.     clr_fl(STDOUT_FILENO, O_NONBLOCK);  
  33.   
  34.     exit(0);  
  35. }  
  36.   
  37.   
  38. //设置文件描述符标志  
  39. void set_fl(int fd, int flags)  
  40. {  
  41.     int val;  
  42.     //获取文件描述符标志  
  43.     if((val = fcntl(fd, F_GETFL, 0)) < 0)  
  44.         err_sys("fcntl F_GETFL error");  
  45.     val |= flags;//添加描述符标志flags  
  46.     //设置文件描述符标志  
  47.     if(fcntl(fd, F_SETFL, val) < 0)  
  48.         err_sys("fcntl F_SETFL error");  
  49. }  
  50. //清除文件描述符标志  
  51. void clr_fl(int fd, int flags)  
  52. {  
  53.     int val;  
  54.     //获取文件描述符标志  
  55.     if((val = fcntl(fd, F_GETFL, 0)) < 0)  
  56.         err_sys("fcntl F_GETFL error");  
  57.     val &= ~flags;//清除描述符标志flags  
  58.     //设置文件描述符标志  
  59.     if(fcntl(fd, F_SETFL, val) < 0)  
  60.         err_sys("fcntl F_SETFL error");  
  61. }  

输出结果:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. ./test </tmp/tmp.sh> temp.file  
  2. read 2778 bytes.  
  3. nwrite = 2778, errno = 0  

fcntl 函数

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /* 
  2. *fcntl函数 
  3. *功能:操纵文件描述符,设置已打开的文件的属性 
  4. int fcntl(int fd, int cmd, ... /* arg */ );  
  5. /*说明: 
  6. *cmd的取值可以如下: 
  7. *复制文件描述符 
  8. *F_DUPFD (long) 
  9. *设置/获取文件描述符标志 
  10. *F_GETFD (void) 
  11. *F_SETFD (long) 
  12. *设置/获取文件状态标志 
  13. *F_GETFL (void) 
  14. *F_SETFL (long) 
  15. *获取/设置文件锁 
  16. *F_GETLK 
  17. *F_SETLK,F_SETLKW 
  18. */  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值