linux - 使用 select() 进行 I/O 多路复用

标签 linux concurrency process io

只是一些关于 I/O 多路复用的问题,我的教科书说:

select 函数会阻塞,直到读取集中的至少一个描述符准备好读取。当且仅当从该描述符读取 1 个字节的请求不会阻塞时,描述符 k 才准备好读取。

Q1-我不明白为什么从描述符中读取 1 个字节可能会阻塞?标准 IO 函数不是使用缓冲区吗?

Q2-为什么不直接 fork 一个子进程,让子进程去做可能会阻塞的工作?

Q3-如果我使用无缓冲系统调用 read() 从两个打开的文件中读取大量字节,所以它们都是阻塞的(需要很长时间),那么 select() 如何进行多路复用?

最佳答案

您误解了 select(2)手册页(另请参阅 select_tut(2) )。顺便说一句,你最好使用 poll(2)在新代码中,例如 this ;因为 select 限制(通过 fd_set 的大小)它可以使用的最高文件描述符(想想 C10K problem )。

select 手册页定义了一个 file descriptor你的process作为准备好 ...

... if it is possible to perform a corresponding I/O operation (e.g., read(2) without blocking, or a sufficiently small write(2)).

也就是说,如果一个文件描述符是这样的,你可以成功 read(2)至少一个字节,它是一个准备好的文件描述符(用于read)。大多数时候,您将能够从中读取几个字节。您无法从中读取 的文件描述符,因为 read(2)尝试会阻塞,还没有准备好,因此可以称为阻塞的文件描述符。

有几种文件描述符被阻塞(即未就绪)的情况。常用的是某网socket(7)或一些 pipe(7) (或某些终端,请参阅 pty(7)the TTY demystified 并注意 line discipline )没有更多输入。这就是为什么需要 poll(或 selectepoll(7) 等...)来编码 event loops。 (特别是在 widget toolkits 中用于 GUI,在 Web 服务器等中),因为你想避免忙 polling .

要进一步解释,请阅读一本不错的 Linux 编程书籍,例如 ALP .

您还可以阅读 Operating Systems: Three Easy Pieces获得更多关于操作系统的知识。

请注意 stdio(3)正在实现缓冲 IO(在 read(2)write(2) 之上)。另见 fflush(3)setvbuf(3) .

另见 proc(5)以编程方式查询进程的状态(其中大部分是 idle 因为在 IO 操作或事件循环中被阻塞)。或者使用 ps(1) , top(1) (两者都在命令中使用 /proc/)。

最后,查看许多free software的源代码项目(例如 Web 服务器、GUI 工具包等)。您可以找到许多使用 selectpoll 的事件循环示例。

关于linux - 使用 select() 进行 I/O 多路复用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54085815/

相关文章:

linux - 是否可以将 Linux 笔记本电脑用作通用直通 USB 嗅探设备?

c++ - 在不处理它的应用程序中使用 unicode/UTF8 处理/清理用户输入

linux - 如何找到 bash 命令?

java - 在单独的线程中预创建对象

c# - 检测进程的内存访问

c - 以 C 开头的 Pthread 函数

linux - 遍历 CSV 文件中的每一列并将不同的值导出到文件

同时更新结构的不同字段——安全吗?

Java:ActionListener.actionPerformed 中的并发

java - 无法使用 launch4j 重命名进程/图像名称