gpt4 book ai didi

linux - STDIN_FILENO 和 STDOUT_FILENO 的非阻塞 I/O 行为很奇怪

转载 作者:太空狗 更新时间:2023-10-29 11:10:36 26 4
gpt4 key购买 nike

我有以下代码:

void
set_fl(int fd, int flags) /* flags are file status flags to turn on */
{
int val;

if ((val = fcntl(fd, F_GETFL, 0)) < 0)
err_sys("fcntl F_GETFL error");

val |= flags; /* turn on flags */

if (fcntl(fd, F_SETFL, val) < 0)
err_sys("fcntl F_SETFL error");
}

int
main(void)
{
char buf[BUFSIZ];
set_fl(STDOUT_FILENO, O_NONBLOCK); //set STDOUT_FILENO to nonblock
if(read(STDIN_FILENO, buf, BUFSIZ)==-1) { //read from STDIN_FILENO
printf("something went wrong with read()! %s\n", strerror(errno));
}
}

如您所见,我将 STDOUT_FILENO 设置为非阻塞模式,但似乎对 STDIN_FILENO 的读取操作立即完成。为什么?

$ ./testprog
something went wrong with read()! Resource temporarily unavailable

谢谢

最佳答案

完全正确:在读取结果后立即执行 errno 打印和 perror 调用导致“资源繁忙”和错误编号 11,或者 EAGAIN/EWOULDBLOCK,如下代码所示:

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>

int main (void) {
char buf;

fcntl (STDOUT_FILENO, F_SETFL, fcntl (STDOUT_FILENO, F_GETFL, 0) | O_NONBLOCK);
fprintf (stderr, "%5d: ", errno); perror("");
read (STDIN_FILENO, &buf, 1);
fprintf (stderr, "%5d: ", errno); perror("");
}

生成:

    0: Success
11: Resource temporarily unavailable

原因是文件描述符有两种不同类型的标志(参见详细说明复制文件描述符的部分中的here):

You can duplicate a file descriptor, or allocate another file descriptor that refers to the same open file as the original. Duplicate descriptors share one file position and one set of file status flags (see File Status Flags), but each has its own set of file descriptor flags (see Descriptor Flags).

第一个是file descriptor flags每个文件描述符确实是唯一的。根据文档,FD_CLOEXEC(在 exec 上关闭)是目前这个阵营中唯一的一个。

所有其他标志都是 file status flags , 并在已复制的文件描述符之间共享。这些包括 I/O operating modes例如 O_NONBLOCK

所以,这里发生的是标准输出文件描述符是从标准输入文件描述符复制的(顺序无关紧要,只是一个是从另一个复制的事实),因此在一个上设置非阻塞模式影响所有重复项(并且可能还包括标准错误文件描述符,尽管我尚未确认)。

在重复的文件描述符上使用阻塞模式通常不是一个好主意,也不是子进程可能继承的文件描述符的好主意 - 这些子进程并不总是善意地拥有他们的标准文件行为不当(从他们的角度来看)。

如果您想要对单个文件描述符进行更细粒度的控制,请考虑使用 select 在尝试读取之前检查描述符。

关于linux - STDIN_FILENO 和 STDOUT_FILENO 的非阻塞 I/O 行为很奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9676991/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com