概述
在Unix系统中,终端I/O的处理是一个复杂而重要的系统功能,用于管理用户与系统之间的交互。
终端I/O之所以如此繁琐,主要是因为它不仅仅应用于普通的终端设备,还包括计算机之间的串口设备
、调制解调器
以及打印机
等各种场景,因此需要兼顾多种设备和复杂的功能需求。
终端I/O工作模式
-
规范模式(Canonical Mode):
- 在这模式下,输入是以行为单位进行处理。终端驱动程序会缓冲输入,直到检测到行结束符(如换行符),才将整行数据提供给程序。
- 适用于需要行编辑功能的应用,比如shell命令输入。用户可以在输入过程中使用诸如退格键等编辑功能。
- 默认情况下,终端设备工作在规范模式。
-
非规范模式(Non-canonical Mode):
- 输入不需要以行为单位进行处理,程序可以立即读取输入的每个字符。
- 适用于需要即时处理输入的应用,比如文本编辑器
vi
,它的命令可能由单个字符组成,并且不以换行符终止。 - 此模式下,特殊字符处理可以被禁用。
终端设备的逻辑结构
终端设备在内核中由终端驱动程序控制,包含:
- 输入队列:
- 用于存储用户输入,受最大长度
MAX_INPUT
限制。 - 如果开启回显功能,输入会被自动回显到输出队列。
- 用于存储用户输入,受最大长度
- 输出队列:
- 用于存储程序输出。
- 当输出队列填满时,内核会让写进程休眠,直到队列有空间。
终端行规程
在Unix系统中,规范输入处理在一个称为终端行规程(terminal line discipline)的模块中完成。这个模块位于通用读、写函数和实际设备驱动程序之间,负责处理终端I/O的详细逻辑。 在使用串口设备时,通常禁用行规程来防止对数据流的处理。
终端设备
在
/dev/
目录下,终端设备通常以 tty
开头。这些设备表示系统中的终端或伪终端。具体来说,包括以下文件名:
tty
tty0
tty1
至tty63
(表示具体的终端设备)ttyS0
至ttyS31
(这是串口终端设备)pts/
(伪终端设备目录,用于虚拟终端)
这些设备是 Linux 系统中用于与用户和其他程序交互的终端接口。
串行端口
串行端口是一种硬件通信接口,用于通过串行方式与其他设备进行通信。在 Linux 中,串行端口通常被映射成设备文件。
例如
/dev/ttySx
:传统串行端口(x 从 0 开始)。/dev/ttyUSBx
:通过 USB 转串口适配器连接的串行端口。
串行端口对应现实存在的物理接口,口通常是一个 UART
(Universal Asynchronous Receiver-Transmitter,通用异步收发器)硬件设备的接口。有TTL
、RS232
、RS485
等多种标准。
虚拟终端
虚拟终端是 Linux 系统中的一种终端抽象,是提供用户与系统交互的虚拟控制台。Linux 的虚拟终端通过键盘和显示器模拟物理终端的功能,通常用于本地登录到系统。
通过Alt+Fn1~12
可以切换虚拟终端界面:
经测试在Fedora下
/dev/tty1绑定GDM程序
/dev/tty2绑定Gnome Shell
/dev/tty3~6绑定tty登陆程序
/dev/tty7~12没有绑定任何程序,只能看到闪烁的光标。
伪终端
伪终端是一种软件实现的终端接口,用于模拟终端行为。伪终端通常用于支持网络终端登录(例如 SSH)或模拟终端程序之间的通信。
我们平常所使用的终端软件,比如ptyxis
gnome-console
Konsole
等被成为终端模拟器。终端模拟器本质上是一个应用程序,它通过伪终端的主设备与操作系统内核和用户进程进行交互。伪终端提供了一个抽象的终端环境,使得终端模拟器可以模拟传统物理终端的行为。
可以尝试通过反复打开或关闭终端软件,观察/dev/pts
目录下内容变化。可以发现一个每个终端窗口对应/dev/pts下的一个设备。
➜ ~ ls /dev/pts0 ptmx