gpt4 book ai didi

c - UNIX 非阻塞 I/O : O_NONBLOCK vs. FIONBIO

转载 作者:太空狗 更新时间:2023-10-29 16:15:18 25 4
gpt4 key购买 nike

在我在 BSD 套接字编程上下文中遇到的每个示例和讨论中,将文件描述符设置为非阻塞 I/O 模式的推荐方法似乎是使用 O_NONBLOCK 标志来 fcntl(),例如

int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);

我在 UNIX 中进行网络编程已有十多年了,并且一直使用 FIONBIO ioctl() 调用来执行此操作:

int opt = 1;
ioctl(fd, FIONBIO, &opt);

从来没有真正想过为什么。就是这么学的

有人对其中一个或另一个可能各自的优点有任何评论吗?我想可移植性轨迹有些不同,但不知道在多大程度上 ioctl_list(2) 没有说明各个 ioctl 方法的那个方面。

最佳答案

在标准化之前,有 ioctl(...FIONBIO...)fcntl(。 ..O_NDELAY...),但这些在系统之间甚至在同一系统内的行为都不一致。例如,FIONBIO 通常在套接字上工作,而 O_NDELAY 在 ttys 上工作,对于管道、fifos 和设备等方面存在很多不一致之处。如果您不知道您拥有哪种文件描述符,则必须同时设置两者才能确定。但除此之外,一个没有可用数据的非阻塞读也被指示不一致;根据操作系统和文件描述符的类型,读取可能会返回 0,或带有 errno EAGAIN 的 -1,或带有 errno EWOULDBLOCK 的 -1。即使在今天,在 Solaris 上设置 FIONBIOO_NDELAY 也会导致没有数据的读取在 tty 或管道上返回 0,或者在套接字上返回 -1 和 errno EAGAIN。然而 0 是不明确的,因为它也为 EOF 返回。

POSIX 通过引入 O_NONBLOCK 解决了这个问题,它具有跨不同系统和文件描述符类型的标准化行为。由于现有系统通常希望避免对可能破坏向后兼容性的行为进行任何更改,因此 POSIX 定义了一个新标志,而不是为其他系统强制执行特定行为。一些系统(如 Linux)对所有 3 个都一视同仁,并且还将 EAGAIN 和 EWOULDBLOCK 定义为相同的值,但是希望保留一些其他遗留行为以实现向后兼容性的系统可以在使用旧机制时这样做。

新程序应该使用 fcntl(...O_NONBLOCK...),作为 POSIX 的标准化。

关于c - UNIX 非阻塞 I/O : O_NONBLOCK vs. FIONBIO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1150635/

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