C select() writefds

发布于 2024-08-16 06:06:14 字数 242 浏览 5 评论 0原文

我无法理解在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

隱形的亼 2024-08-23 06:06:14

这意味着您可以对该 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.

野却迷人 2024-08-23 06:06:14

“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").

半衬遮猫 2024-08-23 06:06:14

是的,FD_ISSET(fd, &writefds) 的真实返回意味着 fd 是可写的。如果在获得 EWOULDBLOCKEAGAIN (至少在 Linux 上等效)后调用 writefds 中设置的 FD 来调用 select() ,它会阻塞直到FD再次可写。

还有更多的事情要做。例如,如果您对其执行了非阻塞 connect()、获得了 EAGAIN 并调用 select(),则 FD 也被认为是可写的 等待连接建立。该建立在 writefds 中发出信号。

Yes, a truthy return from FD_ISSET(fd, &writefds) means fd is writeable. If you call select() with that FD set in the writefds after you get EWOULDBLOCK or EAGAIN (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 got EAGAIN, and call select() to wait for the connection to be established. That establishment is signalled in the writefds.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文