我正在学习
poll
、select
和类似的函数,并且我经常被“会阻塞”这一说法所困扰(它出现在我正在阅读的关于为 Linux 构建驱动程序的书中,也出现在 的手册页上) poll
和 select
)。我真的不明白这一点。什么会被屏蔽?正在读/写文件描述符的进程?读/写操作本身,即当当前进程正在读/写该文件时,没有其他进程能够读/写该文件?
如果这是一个愚蠢的问题,我很抱歉,但我很难在任何地方找到这个问题的答案。
会阻塞意味着进行系统调用的进程将阻塞(等待)直到系统调用返回。 例如,如果您要求程序读取文件,则发出读取命令后,您的程序将等待(阻塞),直到操作系统执行读取并将结果返回给您的程序。
对于多个程序访问同一个文件,多个进程可以读取同一个文件。 但是,当一个或多个进程正在写入一个文件,而另一个或多个进程正在读取同一文件时,您可能(并且通常会)出现竞争条件。 换句话说,阻塞是针对访问文件的单个进程而言的,并且不保证访问同一文件的两个进程之间的操作顺序(例如读取和写入)。 (出于某种原因,我正在考虑文件;管道和套接字的读/写特性与文件系统上的文件的读/写特性有很大不同)。
除了杰夫正确答案:
但是,如果您以非阻塞模式(O_NONBLOCK)打开相应的文件描述符,则可以以非阻塞方式使用大多数系统调用。 该调用始终会立即返回,但如果失败,则会返回 errno 中的 EWOULDBLOCK(并且没有有效数据),您需要在应用程序或驱动程序中自行处理此问题。
让我换个说法。
1) 正常 I/O 是“阻塞”的。 您发出“读取”,您的程序将“等待”直到数据到达或发生错误(或超时)。
2)非阻塞I/O是“不同的”。 您需要某种方法来判断您是否“完成”。
3) 对于“读取”,EWOULDBLOCK 表示“没有任何数据”。 它说“如果这是‘正常 I/O’,那么我会阻止”。
4)对于“写入”,EWOULDBLOCK 表示“第一个缓冲区尚未完全发送和确认 - 您可能需要在发送其他任何内容之前暂停。”
两个链接: