非阻塞I/O

阻塞I/O对应于低速的系统调用,可能会使进程永远阻塞。非阻塞I/O可以使我们发出open、read、write这样的I/O操作,并使这些操作不会永远阻塞。如果这种操作不能完成,则调用立即错误返回,其表示该操作如果继续执行将会阻塞。

对于一个给定的描述符,有两种为其指定非阻塞I/O的方法:

(1)   如果是调用open获得文件描述符,则可指定O_NONBLOCK标志。

(2)   对于一个已经打开的文件描述符,则可以调用fcntl,由该函数打开O_NONBLOCK文件状态标志。

 

如下是一个非阻塞I/O的实例,它从标准输入读500000个字节,并试图将它们写到标准输出上。该程序先将标准输出设置为非阻塞的,然后用for循环进行输出,每次write调用的结果都在标准错误上打印。

 1 [root@benxintuzi IOpri]# cat nonblock.c
 2 #include <unistd.h>
 3 #include <errno.h>
 4 #include <fcntl.h>
 5 #include <stdio.h>
 6 
 7 char buf[500000];
 8 
 9 void set_fl(int fd, int flags);
10 void clr_fl(int fd, int flags);
11 
12 int main(void)
13 {
14         int             ntowrite, nwrite;
15         char*   ptr;
16 
17         ntowrite = read(STDIN_FILENO, buf, sizeof(buf));
18         fprintf(stderr, "read %d bytes\n", ntowrite);
19 
20         set_fl(STDOUT_FILENO, O_NONBLOCK);      /* set nonblocking */
21 
22         ptr = buf;
23         while (ntowrite > 0)
24         {
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                 {
31                         ptr += nwrite;
32                         ntowrite -= nwrite;
33                 }
34         }
35 
36         clr_fl(STDOUT_FILENO, O_NONBLOCK);      /* clear nonblocking */
37 
38         return 0;
39 }
40 
41 void set_fl(int fd, int flags)  /* flags are file status flags to turn on */
42 {
43         int             val;
44 
45         if ((val = fcntl(fd, F_GETFL, 0)) < 0)
46                 printf("fcntl F_GETFL error\n");
47 
48         val |= flags;           /* turn on flags */
49 
50         if (fcntl(fd, F_SETFL, val) < 0)
51                 printf("fcntl F_SETFL error\n");
52 }
53 
54 void clr_fl(int fd, int flags)  /* flags are the file status flags to turn off */
55 {
56         int             val;
57 
58         if ((val = fcntl(fd, F_GETFL, 0)) < 0)
59                 printf("fcntl F_GETFL error\n");
60 
61         val &= ~flags;          /* turn flags off */
62 
63         if (fcntl(fd, F_SETFL, val) < 0)
64                 printf("fcntl F_SETFL error\n");
65 }
66 
67 [root@benxintuzi IOpri]# gcc nonblock.c -o nonblock
68 [root@benxintuzi IOpri]# ./nonblock < nonblock.c > temp.file
69 read 1246 bytes
70 nwrite = 1246, errno = 0
71 [root@benxintuzi IOpri]# ls -l temp.file
72 -rw-r--r--. 1 root root 1246 Sep  1 23:38 temp.file
View Code

相关文章:

  • 2021-12-22
  • 2021-09-18
  • 2021-07-07
  • 2021-10-10
  • 2022-02-07
  • 2021-12-02
  • 2021-09-11
猜你喜欢
  • 2022-01-08
  • 2022-01-02
  • 2022-12-23
  • 2022-01-19
  • 2021-12-19
  • 2021-08-20
相关资源
相似解决方案