O_NONBLOCK是否设置了文件描述符或基础文件的属性?

时间:2010-05-22 21:53:44

标签: c nonblocking file-descriptor fcntl posix-api

根据我在开放小组网站fcntlopenreadwrite上所阅读的内容,我得到的结论是{{1}在文件描述符上设置,因此非阻塞I / O是否与描述符一起使用,应该是该文件描述符的属性而不是底层文件。作为文件描述符的属性意味着,例如,如果我复制文件描述符或打开另一个描述符到同一个文件,那么我可以使用阻塞I / O与另一个阻塞I / O. < / p>

尝试使用FIFO,似乎不可能同时为FIFO提供阻塞I / O描述符和非阻塞I / O描述符(因此设置O_NONBLOCK是否属性底层文件[FIFO]):

O_NONBLOCK

这让我想到:是否有可能拥有一个非阻塞I / O描述符并阻止I / O描述符到同一个文件,如果是这样,它是否依赖于文件类型(常规文件,FIFO,阻止特殊文件,字符特殊文件,套接字等)?

1 个答案:

答案 0 :(得分:27)

O_NONBLOCK是打开文件描述的属性,不是文件描述符的属性,也不是基础文件的属性。

是的,你可以为同一个文件打开单独的文件描述符,其中一个是阻塞的,另一个是非阻塞的。

您需要区分FIFO(使用mkfifo()创建)和管道(使用pipe()创建)。

请注意,阻止状态是“打开文件描述”的属性,但在最简单的情况下,文件描述符和打开文件描述之间存在一对一的映射。 open()函数调用创建一个新的打开文件描述和一个引用打开文件描述的新文件描述符。

使用dup()时,您有两个文件描述符共享一个打开的文件描述,属性属于打开的文件描述。 fcntl()的描述表明F_SETFL会影响与文件描述符关联的打开文件描述。请注意,lseek()调整与文件描述符关联的打开文件描述的文件位置 - 因此它会影响与原始文件描述符重复的其他文件描述符。

从代码中删除错误处理以减少它,你有:

int fds[2];
pipe(fds);
int fd0_dup = dup(fds[0]);
fcntl(fd0_dup, F_SETFL, fcntl(fd0_dup, F_GETFL) | O_NONBLOCK);

现在fd0_dup和fds [0]都引用相同的打开文件描述(因为dup()),因此fcntl()操作影响了两个文件描述符。

if ((fcntl(fds[0], F_GETFL) & O_NONBLOCK)) { ... }

因此,这里观察到的行为是POSIX所必需的。