【问题标题】:when a file descriptor is ready to read?什么时候准备好读取文件描述符?
【发布时间】:2019-06-03 16:10:02
【问题描述】:

我是 Linux 的初学者,仍在努力理解文件描述符和读取文件。 我的教科书说:

“当且仅当从该描述符读取 1 个字节的请求不会阻塞时,描述符 k 才准备好读取”

假设一个磁盘文件有 20 个字节,我刚刚打开这个文件并准备读取它,所以它有一个文件描述符(假设 fd 为 3)。那么在什么情况下这个文件描述符没有1个字节可以读取呢?是不是我第一次读取 20 个字节,然后尝试读取另外 20 个字节会阻塞?谁能给我一个这个例子的场景。谢谢

【问题讨论】:

    标签: linux io


    【解决方案1】:

    磁盘文件始终准备好读取,它永远不会阻塞。当您打开文件时,它会准备就绪,您将读取 20 个字节。之后,您将读取 EOF(由 read() 指示,返回长度为 0)。

    “ready to read”的概念适用于异步设备,例如终端和网络套接字。在用户输入内容之前,终端不会准备好阅读(并且如果终端处于正常的“cooked”模式,当他们使用 Enter 或 EOF 击键发送它时)。当从远程机器接收到数据时,网络套接字将准备好读取。

    【讨论】:

    • 对于磁盘文件,如果遇到 EOF,之后的任何读取都将永远阻塞,因为没有字节可以读取了,对吗?对于终端,如果我只是键入内容但不按 Enter,则在我按 Enter 之前,终端仍然无法阅读,我的理解是否正确?
    • 没有。你的书正在谈论select()。 1) 首先,您指定要在哪些文件描述符上“select()”,2) 然后,使用已完成的 fd_set 调用“select”。 3) 选择块直到有一个或多个文件描述符准备好。 4)选择取消块时,只能从“准备就绪”的描述符中读取。 5)您不要尝试从未准备好的描述符中读取。如果您尝试,“读取”通常会返回一个错误。它不会只是阻塞。
    • @paulsm4 是的,除非您在描述符上设置O_NONBLOCK 模式,否则它将阻塞。
    • @amjad 使用磁盘文件,遇到EOF时不会阻塞,每次调用它只会返回0
    【解决方案2】:

    “经典”Linux 文件 I/O 使用 "blocking calls",与 Javascript 中常见的 "Asynchronous I/O" 形成对比。这意味着如果你想“读”或“写”一些东西……程序“阻塞”直到 I/O 操作完成。

    如果您只想“阅读”一件事,这很好用。如果您想阅读任何 SEVERAL 不同的东西,它不起作用。例如,如果您有一个“事件”循环等待任何鼠标、键盘或窗口事件。

    我相信您的教科书正在讨论 select() 函数,它允许函数阻塞,直到一个或多个输入有可用数据。

    这真的不是关于“这个磁盘文件有一个字节还是二十个字节?”相反,使用“选择”可以“多路复用”多个并发输入。

    您可能还会发现这篇文章有帮助:

    Linux – IO Multiplexing – Select vs Poll vs Epoll

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-22
      • 1970-01-01
      • 2011-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多