C 当为stdout打开非阻塞I/O时,操作系统是否也为stdin打开它?
我注意到在OSX和Linux上都出现了一些意想不到的行为。为标准输出打开非阻塞I/O(使用C 当为stdout打开非阻塞I/O时,操作系统是否也为stdin打开它?,c,linux,macos,posix,C,Linux,Macos,Posix,我注意到在OSX和Linux上都出现了一些意想不到的行为。为标准输出打开非阻塞I/O(使用O\u NONBLOCK)也会为标准输入打开它 这些操作系统运行正常吗?如果是,这种行为是由POSIX定义的吗?如果是这种情况,请向我提供相关文件 下面是我用来测试的一个示例程序: #include <fcntl.h> #include <stdio.h> #include <string.h> #include <unistd.h> int main (i
O\u NONBLOCK
)也会为标准输入打开它
这些操作系统运行正常吗?如果是,这种行为是由POSIX定义的吗?如果是这种情况,请向我提供相关文件
下面是我用来测试的一个示例程序:
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main (int argc, char *argv[]) {
int flags = fcntl(STDOUT_FILENO, F_GETFL);
if (argc > 1 && strcmp(argv[1], "1") == 0) {
fcntl(STDOUT_FILENO, F_SETFL, flags | O_NONBLOCK);
}
printf("stdout O_NONBLOCK is: %d\n", fcntl(STDOUT_FILENO, F_GETFL) & O_NONBLOCK);
printf("stdin O_NONBLOCK is: %d\n", fcntl(STDIN_FILENO, F_GETFL) & O_NONBLOCK);
return 0;
}
在Linux上:
$ gcc -o fd-test fd-test.c
$ ./fd-test
stdout O_NONBLOCK is: 0
stdin O_NONBLOCK is: 0
$ ./fd-test 1
stdout O_NONBLOCK is: 2048
stdin O_NONBLOCK is: 2048
从shell启动进程时,
stdin
、stdout
和stderr
指向相同的文件描述。您的fcntl(1)
调用将此文件描述标记为O\u非块
,因此预期两个文件描述符都标记为O\u非块
如果确实希望从两个文件描述符写入同一文件,但希望其中一个标记为O_NONBLOCK
,则需要为同一文件创建新的文件描述。如果您知道相关文件的文件名,只需使用所需的文件名和标志调用open()
,即可实现此目的。在某些操作系统上,您可以使用特定于平台的API找到文件名,例如/proc/fd
虚拟文件系统(包括Linux在内的许多Unice)或Plan 9中的fd2path()
函数。有关更多详细信息,请参阅
请注意,简单地调用
open(“/dev/fd/0”,…)
可能无法正常工作,因为如果我没有记错的话,它会返回指向某些平台上相同文件描述的指针。也许应该注意到,文件描述与文件描述符非常相似,但又不同。@n.m.嗯,stdin,根据定义,stdout和stderr是不同的文件描述符,所以我不认为有任何歧义。请随意编辑我的答案。答案本身没有歧义。由于术语的不幸相似性,只有潜在的混淆。如何才能做到这一点?如果我使用pipe()
或socketpair()
,我可以设置一个非阻塞而不设置另一个。请注意,如果进程在管道中,则stdin和stdout是不同的文件描述符!尝试echo hello |/fd text
$ gcc -o fd-test fd-test.c
$ ./fd-test
stdout O_NONBLOCK is: 0
stdin O_NONBLOCK is: 0
$ ./fd-test 1
stdout O_NONBLOCK is: 2048
stdin O_NONBLOCK is: 2048