为什么非阻塞写入磁盘不会返回EAGAIN或EWOULDBLOCK?

时间:2015-02-15 03:56:46

标签: c linux kernel nonblocking system-calls

我从APUE修改了一个程序,程序首先打开一个文件,然后将fd标记为非阻塞,然后继续写入fd直到写入返回-1。

我认为由于磁盘I / O很慢,当OS中的写缓冲区接近满时,写系统调用将返回-1,而errno应该是EAGAIN或EWOULDBLOCK。

但我运行程序大约几分钟,我重复运行程序几次,写入系统调用没有返回-1甚至一次!为什么? 这是代码:

#include "apue.h"
#include <errno.h>
#include <fcntl.h>

char    buf[4096];

int
main(void)
{
        int nwrite;

        int fd = open("a.txt", O_RDWR);
        if(fd<0){
            printf("fd<0\n");
            return 0;
        }
        int  i;
        for(i = 0; i<sizeof(buf); i++)
            buf[i] = i*2;

        set_fl(fd, O_NONBLOCK); /* set nonblocking */

        while (1) {
                nwrite = write(fd, buf, sizeof(buf));
                if (nwrite < 0) {
                    printf("write returned:%d, errno=%d\n", nwrite, errno);
                    return 0;
                }
        }

        clr_fl(STDOUT_FILENO, O_NONBLOCK);      /* clear nonblocking */

        exit(0);
}

1 个答案:

答案 0 :(得分:3)

O_NONBLOCK标志主要对表示流(例如,管道,套接字和字符设备)的文件描述符有意义,它可以防止读取和写入操作在没有数据等待读取时阻塞,或缓冲区太满了,不能再写更多东西了。它对打开常规文件的文件描述符没有影响;磁盘I / O延迟基本上被系统忽略。

如果要对文件执行异步I / O,可能需要查看the POSIX AIO interface。但请注意,它很有毛,很少使用。