正在设置的O_NONBLOCK是文件描述符或底层文件的属性吗?

正在设置的O_NONBLOCK是文件描述符或底层文件的属性吗?,c,nonblocking,file-descriptor,fcntl,posix-api,C,Nonblocking,File Descriptor,Fcntl,Posix Api,从我在、和的Open Group网站上读到的内容来看,我得到的印象是,是否在文件描述符上设置了O_NONBLOCK,以及是否将非阻塞I/O与描述符一起使用,应该是该文件描述符的属性,而不是底层文件的属性。作为文件描述符的一个属性意味着,例如,如果我复制一个文件描述符或打开另一个描述符到同一个文件,那么我可以使用一个阻塞I/O和另一个非阻塞I/O 然而,在试验FIFO时,似乎不可能同时向FIFO提供阻塞I/O描述符和非阻塞I/O描述符(因此是否设置了O_NONBLOCK,是基础文件[FIFO]的一

从我在、和的Open Group网站上读到的内容来看,我得到的印象是,是否在文件描述符上设置了
O_NONBLOCK
,以及是否将非阻塞I/O与描述符一起使用,应该是该文件描述符的属性,而不是底层文件的属性。作为文件描述符的一个属性意味着,例如,如果我复制一个文件描述符或打开另一个描述符到同一个文件,那么我可以使用一个阻塞I/O和另一个非阻塞I/O

然而,在试验FIFO时,似乎不可能同时向FIFO提供阻塞I/O描述符和非阻塞I/O描述符(因此是否设置了
O_NONBLOCK
,是基础文件[FIFO]的一个属性):

#包括
#包括
#包括
#包括
#包括
int main(int argc,字符**argv)
{
int-fds[2];
如果(管道(fds)=-1){
fprintf(stderr,“`pipe`失败。\n”);
返回退出失败;
}
int fd0_dup=dup(fds[0]);

if(fd0_dupO_NONBLOCK是打开文件描述的属性,不是文件描述符的属性,也不是基础文件的属性

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

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

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

使用时,两个文件描述符共享一个打开的文件描述,属性属于打开的文件描述。的描述表示F_SETFL影响与文件描述符关联的打开的文件描述。请注意,调整与文件描述符关联的打开的文件描述的文件位置或者-因此它会影响从原始文件描述符复制的其他文件描述符

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

int fds[2];
pipe(fds);
int fd0_dup = dup(fds[0]);
fcntl(fd0_dup, F_SETFL, fcntl(fd0_dup, F_GETFL) | O_NONBLOCK);
现在
fd0\u dup
fds[0]
都引用了相同的打开文件描述(因为
dup()
),因此
fcntl()
操作影响了两个文件描述符

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

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

我想知道这一点,因为如果设置的O_NONBLOCK是底层文件的属性,那么调用打开一个在oflags中未设置O_NONBLOCK的文件可能会返回一个带有O_NONBLOCK标志的文件描述符。哦,好吧。所以“文件描述符”之间有区别和“文件描述”。两个文件描述符可以共享同一个文件描述,并且标志是描述的属性。再次查看要打开的文档,它表示函数“应创建打开的文件描述”。我想我现在明白了。@DanielTrebbien:有些标志属于文件描述符,例如,
FD\u CLOEXEC
“O\u NONBLOCK是打开的文件描述符的属性,不是文件描述符的属性,也不是底层文件的属性。”我不明白“打开的文件描述符”、“文件描述符”之间的区别以及后面提到的“打开的文件描述”。它们都是唯一和独立的吗?@TomE:有“打开的文件描述”和“打开的文件描述”",两者是分开的。但是,第一句话中有一个bug,我将要修复。该bug是由2021-01-08年的一次编辑引入的,在该次编辑中,我已经回滚,因为它完全颠覆了我所说的内容。我不确定当时我是如何错过编辑的;我可能已经收到通知。它再次被修复。你可以n在答案中的链接中找到有关“打开文件描述符”和“打开文件描述”的信息,特别是指向
open()
的POSIX规范的链接。
if ((fcntl(fds[0], F_GETFL) & O_NONBLOCK)) { ... }