You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何C语言中read()调用会阻塞等待换行符?

问题解答:为何终端下read()会阻塞至换行符才返回

首先看你实现的简易cat代码:

#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>

int main() {
  char buffer[4096];
  ssize_t bytes_read;
  while ( ( bytes_read = read(STDIN_FILENO, buffer, sizeof buffer) ) > 0) {
    ssize_t bytes_written = write(STDOUT_FILENO, buffer, bytes_read);
    if (bytes_written == -1) return errno;
    assert(bytes_read == bytes_written);
  }
  if (bytes_read == -1) return errno;
  assert(bytes_read == 0);
  return 0;
}

你遇到的核心问题,根源不在read()系统调用本身,而是终端默认的工作模式——规范模式(Canonical Mode)。

关键细节拆解:

  • 终端设备默认处于规范模式,这种模式下终端会充当一个行编辑器:它会缓存你输入的所有字符,直到收到换行符(\n)、EOF信号(比如按下Ctrl+D),或者完成退格、删除等编辑操作后,才会把整行数据交给内核。此时read()才能从内核读取到数据,所以你会看到它阻塞到换行才返回。
  • read()的行为完全依赖于它操作的文件描述符对应的对象特性:
    • 对于普通磁盘文件,read()会立即返回当前可用的数据(哪怕只有1字节);
    • 对于终端这种字符设备,它的输入行为由终端的配置参数控制,read()只是被动等待内核提供数据。
  • 你可以手动修改终端模式验证:运行stty -icanon关闭规范模式,再执行你的cat程序,此时输入单个字符就会立即被输出,不会等待换行。如果要恢复默认,运行stty icanon即可。

关于EOF的补充:

你之前对read()返回值的理解有偏差:

  • read()返回-1是发生错误(比如文件描述符无效、被信号中断等);
  • 返回0表示没有更多数据可读,这既包括文件被关闭的场景,也包括终端在规范模式下按下Ctrl+D(此时终端告知内核没有更多输入)的情况。

内容的提问来源于stack exchange,提问作者user129393192

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 14:45:15