我和我的朋友在理解代码方面有问题。我们不明白为什么在最后要检查nread是否为!= 1。如果有人能帮助我们,我们将非常高兴。
while ((nread = read(STDIN_FILENO, &c, 1)) != 1) { if (nread == -1 && errno != EAGAIN) quit("read"); }
ybzsozfc1#
它使循环仅在读取成功时退出。也就是说,代码有缺陷。呼叫read会传回下列其中一项:
read
count
由于对read的此特定调用仅尝试读取一个字节,因此以下是可能返回的值:
那么,让我们把这个片段作为一个整体来看。
这是有问题的,原因有二。
当没有数据可用时,非阻塞句柄返回EAGAIN。因此,这是一个忙等待循环(占用CPU)。这是不可接受的。此外,如果句柄可以是套接字,则可以返回EWOULDBLOCK而不是EAGAIN。这根本不进行处理。
在EOF时,它试图再次读取。这很糟糕。现在,可以在某些句柄返回EOF后读取它们。具体来说,终端可以在返回EOF后重置它们的EOF状态。但不能保证STDIN就是终端。而且即使知道STDIN是终端,它仍然可以像其他句柄一样返回无休止的EOF流。
1条答案
按热度按时间ybzsozfc1#
它使循环仅在读取成功时退出。
也就是说,代码有缺陷。
呼叫
read
会传回下列其中一项:count
],读取的字节数。由于对
read
的此特定调用仅尝试读取一个字节,因此以下是可能返回的值:那么,让我们把这个片段作为一个整体来看。
这是有问题的,原因有二。
当没有数据可用时,非阻塞句柄返回EAGAIN。因此,这是一个忙等待循环(占用CPU)。这是不可接受的。
此外,如果句柄可以是套接字,则可以返回EWOULDBLOCK而不是EAGAIN。这根本不进行处理。
在EOF时,它试图再次读取。这很糟糕。
现在,可以在某些句柄返回EOF后读取它们。具体来说,终端可以在返回EOF后重置它们的EOF状态。但不能保证STDIN就是终端。而且即使知道STDIN是终端,它仍然可以像其他句柄一样返回无休止的EOF流。