在每个例子和讨论中,我在BSD套接字编程的上下文中运行,似乎将文件描述符设置为非阻塞I / O模式的推荐方法是使用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可以在tty上工作,对于管道,fifos和设备之类的东西有很多不一致。如果你不知道你有什么样的文件描述符,你必须设置两者以确保。但是,另外,还没有一致地指示没有数据可用的非阻塞性读取;根据操作系统和文件描述符的类型,读可能返回0,或者带errno EAGAIN的-1,或者带errno EWOULDBLOCK的-1。即使在今天,在Solaris上设置FIONBIO或O_NDELAY也会导致在tty或管道上没有数据返回0的读取,或在套接字上使用errno EAGAIN返回-1。但是0是不明确的,因为它也为EOF返回。
原文链接:https://www.f2er.com/bash/392488.htmlPOSIX通过引入O_NONBLOCK来解决这个问题,O_NONBLOCK在不同的系统和文件描述符类型之间具有标准化的行为。因为现有系统通常希望避免任何可能破坏向后兼容性的行为更改,POSIX定义了一个新标志,而不是强制其中一个特定行为。一些系统像Linux一样对待所有3,并且还将EAGAIN和EWOULDBLOCK定义为相同的值,但是希望保留一些其他遗留行为以实现向后兼容性的系统在使用旧机制时可以这样做。
新程序应该使用fcntl(… O_NONBLOCK …),由POSIX标准化。