终端的启动流程

本文深入探讨了Linux操作系统中进程的启动与管理机制,详细解析了init进程作为系统所有进程的根,以及如何通过fork和exec产生其他进程。同时,介绍了终端设备与进程之间的关系,包括如何通过设备文件访问控制终端,以及ttyname函数的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在Linux操作系统启动时,首先加载的进程就是init进程(ID为1),其余进程都是init进程产生的(fork,然后exec金蝉脱壳),因此系统中所有进程都可以看成是init进程的子孙进程。可以通过ps ajx命令查看任意进程的父进程,进行追溯可以发现,任意进程的开头都是init进程,init进程起源于0号进程,0号进程实际不存在。

文件与I/O中讲过,每个进程都可以通过一个特殊的设备文件/dev/tty访问它的控制终端。事实上每个终端设备都对应一个不同的设备文件(伪文件,不占用磁盘空间),/dev/tty提供了一个通用的接口,一个进程要访问它的控制终端既可以通过/dev/tty也可以通过该终端设备所对应的设备文件来访问。ttyname函数可以由文件描述符查出对应的文件名,该文件描述符必须指向一个终端设备而不能是任意文件。

终端的启动过程。简单来说,一个Linux系统启动,大致经历如下的步骤: init --> fork --> exec --> getty --> 用户输入帐号 --> login --> 输入密码 --> exec --> bash(文字终端)。init进程通过fork产生子进程,子进程调用exec函数族成为getty进程,即文字终端登陆界面,登陆成功后再调用exec函数族成为bash终端进程,在该终端中产生的任意子进程的控制终端都是该终端。对于设备终端,init进程fork子进程后,exec提供登陆界面,再exec成为桌面终端,再exec成为设备终端(伪终端)。

计算机的整个架构:计算机硬件→硬件驱动程序→系统调用→应用层,数据流的流向也是如此,对于输入则为硬件流向应用层(用户空间),对于输出则相反。硬件驱动程序负责读写实际的硬件设备(包括各种文件,磁盘),比如从键盘读入字符和把字符输出到显示器,线路规程(line disciline像一个过滤器(用来过滤键盘输入的内容),对于某些特殊字符并不是让它直接通过,而是做特殊处理,比如在键盘上按下Ctrl-z,对应的字符并不会被用户程序的read读到,而是被线路规程截获,解释成SIGTSTP信号发给前台进程,通常会使该进程停止。线路规程应该过滤哪些字符和做哪些特殊处理是可以配置的。

ttyname函数

由文件描述符查出对应的文件名,该文件描述符必须指向一个终端设备而不能是任意文件。

char *ttyname(int fd);     成功:终端名;失败:NULL,设置errno

//下面我们借助ttyname函数,通过实验看一下各种不同的终端所对应的设备文件名

#include <unistd.h>
#include <stdio.h>
int main(void)
{
    printf("fd 0: %s\n", ttyname(0));
    printf("fd 1: %s\n", ttyname(1));
    printf("fd 2: %s\n", ttyname(2));
    return 0;
}

[root@localhost 01_session_daemon_test]# ./ttyname

fd 0: /dev/pts/2

fd 1: /dev/pts/2

fd 2: /dev/pts/2    //可以看见标准输入、输出和错误输出对应的终端为pts/2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值