UNIX非阻塞I / O:O_NONBLOCK与FIONBIO [英] UNIX nonblocking I/O: O_NONBLOCK vs. FIONBIO

查看:1905
本文介绍了UNIX非阻塞I / O:O_NONBLOCK与FIONBIO的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In every example and discussion I run across in the context of BSD socket programming, it seems that the recommended way to set a file descriptor to nonblocking I/O mode is using the flag to fcntl(), e.g.

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

我一直在做网络编程在UNIX了十多年,并一直使用了 FIONBIO的ioctl()调用做到这一点:

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

从来没有真正花了不少认为这是为什么。刚刚得知这种方式。

Never really gave much thought to why. Just learned it that way.

有没有人有一个或另一个可能的各自优点的评论?我想象可移植性轨迹有所不同,但不知道到什么程度为 ioctl_list(2)并没有单独的的ioctl <的那个方面讲/ code>方法。

Does anyone have any commentary on the possible respective merits of one or the other? I imagine the portability locus differs somewhat, but do not know to what extent as ioctl_list(2) doesn't speak to that aspect of individual ioctl methods.

推荐答案

在标准化之前有的ioctl( ... FIONBIO ... 的fcntl( ... O_NDELAY ... ,但这些系统之间的行为不一致,甚至在同一系统内。例如,它是常见的 FIONBIO 在插座工作, O_NDELAY 在ttys中工作,有很多不一致对于像管道,FIFO和设备。如果你不知道你有什么样的文件描述符,你必须同时设置以确保万无一失。但除此之外,非阻塞读取无可用数据也不一致指示;这取决于操作系统和文件描述符的类型上读取可能会返回0,或-1,并将errno EAGAIN,或-1,并将errno EWOULDBLOCK。即使在今天,设置 FIONBIO O_NDELAY 在Solaris导致没有数据读取到一个tty或管道返回0,或-1用套筒上的errno EAGAIN。但是0是不明确的,因为它也是EOF返回。

Prior to standardization there was ioctl(...FIONBIO...) and fcntl(...O_NDELAY...), but these behaved inconsistently between systems, and even within the same system. For example, it was common for FIONBIO to work on sockets and O_NDELAY to work on ttys, with a lot of inconsistency for things like pipes, fifos, and devices. And if you didn't know what kind of file descriptor you had, you'd have to set both to be sure. But in addition, a non-blocking read with no data available was also indicated inconsistently; depending on the OS and the type of file descriptor the read may return 0, or -1 with errno EAGAIN, or -1 with errno EWOULDBLOCK. Even today, setting FIONBIO or O_NDELAY on Solaris causes a read with no data to return 0 on a tty or pipe, or -1 with errno EAGAIN on a socket. However 0 is ambiguous since it is also returned for EOF.

POSIX解决了这个引进 O_NONBLOCK ,其中有跨不同系统和文件描述符类型规范行为。由于现有的系统通常要避免可能打破向后兼容性的行为进行任何更改,POSIX定义了一个新的标志,而不是强制要求的特定行为对于他人之一。如Linux有些系统对待所有3相同,并且还定义EAGAIN和EWOULDBLOCK相同的价值,但系统希望保持向后兼容其他一些传统行为可以这样做,当使用较旧的机制。

POSIX addressed this with the introduction of O_NONBLOCK, which has standardized behavior across different systems and file descriptor types. Because existing systems usually want to avoid any changes to behavior which might break backward compatibility, POSIX defined a new flag rather than mandating specific behavior for one of the others. Some systems like Linux treat all 3 the same, and also define EAGAIN and EWOULDBLOCK to the same value, but systems wishing to maintain some other legacy behavior for backward compatibility can do so when the older mechanisms are used.

新程序应该使用的fcntl( ... O_NONBLOCK ... ,由POSIX标准。

New programs should use fcntl(...O_NONBLOCK...), as standardized by POSIX.

这篇关于UNIX非阻塞I / O:O_NONBLOCK与FIONBIO的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆