C select() writefds
我无法理解在 Linux 中为 select() 设置的 writefds 添加描述符意味着什么。我编写了一些简单的代码,将 stdout 的描述符添加到 writefds 集中,并使用 NULL 超时。现在,我的代码只是无限循环检查是否设置了该描述符,如果设置了,则打印“WRITING”。当我运行代码时,它只是不断打印“WRITING”到无穷大。当我为标准输入执行此操作时,也会发生同样的事情。同样,循环中没有其他代码。 stdin/stdout 总是准备好写入吗?
I am having trouble understanding what it means to add a descriptor to writefds set for select() in linux. I wrote some simple code that adds the descriptor for stdout to the writefds set and uses a timeout of NULL. Now, my code just infinite loops checking if this descriptor is set, and if it does, it prints "WRITING". When I run my code it just keeps printing "WRITING" to infinity. The same thing happens when I do this for stdin. Again, there is no other code in the loop. Are stdin/stdout always just ready for writing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这意味着您可以对该 fd 调用 write,并且内核承诺不会阻塞并消耗至少 1 个字节。
更多细节。如果您的套接字未处于非阻塞模式并且与套接字关联的内核缓冲区已满,则内核将使您的线程进入睡眠状态,直到它可以清空一些缓冲区并能够消耗部分写入内容。
如果您的套接字处于非阻塞模式并且内核缓冲区已满,则写入将立即返回而不消耗任何字节。
It means you can call write on that fd and the kernel promises to not-block and consume at least 1 byte.
More details. If your socket is not in non-blocking mode and the kernel buffers associated with the socket are full, the kernel will put your thread to sleep until it can empty some of the buffer and be able to consume part of your write.
If your socket is in non-blocking mode and the kernel buffers are full, the write will return immediately without consuming any bytes.
“stdout 是否始终准备好写入”这个问题的答案是“这取决于情况”。
stdout 可以连接到任何可以作为文件描述符打开的东西 - 例如磁盘文件、网络套接字或管道。通常的情况是它连接到终端设备。
大多数这些类型的文件描述符都会在写入时阻塞(这意味着它们在
select()
返回后可能不会被标记为可写),但通常仅当您刚刚写入大量数据时它们(因此填充了某种缓冲区)。 “大量”因设备类型而异 - 如果您的标准输出终端是 9600 波特串行设备,那么您可以很容易地填充写入缓冲区; xterm,没那么多。某些设备永远不会阻塞 - 例如磁盘文件或
/dev/null
。 (写入磁盘文件的 write() 可能不会立即完成,但这不被视为“阻塞” - 它是“磁盘等待”)。The answer to the question "Is stdout always ready for writing" is "It depends."
stdout can be connected to anything that can be opened as a file descriptor - like a disk file, a network socket, or a pipe. The usual case is that it's connected to a terminal device.
Most of these types of file descriptors can block on writing (which means they might not be marked writeable after
select()
returns), but usually only if you're just written a very large amount of data to them (and so filled some kind of buffer). "Large amount" varies between the device types - if your stdout terminal is a 9600 baud serial device, then you could fill the write buffer pretty easily; an xterm, not so much.Some device will never block - like disk files, or
/dev/null
, for example. (write()
to a disk file might not complete immediately, but this isn't considered "blocking" - it's a "disk wait").是的,
FD_ISSET(fd, &writefds)
的真实返回意味着fd
是可写的。如果在获得EWOULDBLOCK
或EAGAIN
(至少在 Linux 上等效)后调用 writefds 中设置的 FD 来调用select()
,它会阻塞直到FD再次可写。还有更多的事情要做。例如,如果您对其执行了非阻塞
connect()
、获得了EAGAIN
并调用select(),则 FD 也被认为是可写的
等待连接建立。该建立在 writefds 中发出信号。Yes, a truthy return from
FD_ISSET(fd, &writefds)
meansfd
is writeable. If you callselect()
with that FD set in the writefds after you getEWOULDBLOCK
orEAGAIN
(equivalent on Linux, at least) it blocks until the FD is again writeable.There's more to it than that. For instance, an FD is also considered writeable if you've done a non-blocking
connect()
on it, you gotEAGAIN
, and callselect()
to wait for the connection to be established. That establishment is signalled in the writefds.