【Linux】会话、终端、前后台进程

目录

会话是什么

终端是什么

前台进程与后台进程


会话是什么

会话 是 Linux/Unix 系统中进程管理的核心概念之一。可以把会话理解为一个用户登录到退出的一次完整交互过程 ,它将一组相关的进程组织在一起,并关联到一个控制终端

1. 会话的本质

会话(Session) 是一个进程集合,具有以下特征:

  • 由一个会话首进程(通常是登录 Shell)创建。

  • 所有属于该会话的进程共享一个控制终端(可选)。

  • 会话中的进程分为前台进程组多个后台进程组

  • 同一会话的进程的**会话ID(sID)**相同

  • 当控制终端关闭或会话首进程终止时,会话中的所有进程都会收到 SIGHUP 信号。

每次你打开一个终端窗口,或者通过 SSH 登录系统,系统就会为你创建一个新的会话。这个会话就像一个"容器",把你接下来运行的所有进程都装在里面,直到你退出登录或关闭窗口。

2. 会话的层级结构

会话内部有清晰的层级关系:

复制代码
会话 (Session)
├── 控制终端 (Controlling Terminal) ------ 通常是 /dev/tty* 或 /dev/pts/*
└── 进程组 (Process Groups)
    ├── 前台进程组 (Foreground Process Group)
    │   └── 当前正在运行的进程(如 vim、top、正在执行命令的 Shell)
    └── 后台进程组 (Background Process Groups)
        ├── 后台作业1(如 sleep 100 &)
        ├── 后台作业2(如 find / -name "*.txt" &)
        └── ...
  • 进程组 :由一个组长进程创建,一组相关进程的集合(如一个管道 cmd1 | cmd2 | cmd3 中的所有进程属于同一进程组,cmd1 是组长)。单个启动的进程,如 ./test,自成一组。进程组与任务的关系:一个进程组被指派一个任务。

  • 会话:由一个或多个进程组组成。

  • 控制终端:会话关联的终端设备,负责输入分发和信号传递。

字段 含义
PPID 父进程ID
PID 进程ID
PGID 进程组ID,一组相关进程的标识
SID 会话ID,一组进程组的标识
TTY 关联的终端(? 表示无终端,如守护进程)
TPGID 终端前台进程组ID(控制终端当前前台进程组)
STAT 进程状态
UID 启动该进程的用户ID
TIME 进程累计占用CPU的时间
COMMAND 命令名称及参数

守护进程

我们平时创建的进程,会收到用户登陆和退出的影响,而守护进程自成一个会话,不会受到用户登陆和退出的影响。那如何让一个进程变成守护进程呢?

setsid - 创建新会话

cpp 复制代码
#include <unistd.h>

pid_t setsid(void);
  • 成功:返回新会话的 SID(等于调用进程的 PID)

  • 失败:返回 -1,并设置 errno

主要作用

  1. 创建新会话:调用进程成为新会话的唯一成员

  2. 创建新进程组:调用进程成为新进程组的组长

  3. 脱离终端:如果调用进程之前有控制终端,会失去该终端(成为无终端进程)

使用方法

  • 调用进程不能是进程组组长(否则返回错误)

  • 通常做法:1、忽略一些异常信号,比如 SIGCLD、SIGPIPE、SIGSTOP。2、先 fork(),父进程直接退出,子进程调用 setsid()。3、更改调用进程的当前工作目录。4、由于子进程调用 setsid()后标准输入/输出/错误仍指向已关闭的文件描述符,所以将标准输入/输出/错误重定向至 /dev/null(/dev/null:所有向 /dev/null 写入的字符串,会被自动丢弃,输出 /dev/null 的内容,结果为空白)。最好不要直接关闭0,1,2 文件描述符作为解决方案。

  • 守护进程的进程名通常以 d 结尾。

cpp 复制代码
#pragma once

#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <signal.h>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

const std::string nullfile = "/dev/null";

void Daemon(const std::string &cwd = "")
{
    // 1. 忽略其他异常信号
    signal(SIGCLD, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);
    signal(SIGSTOP, SIG_IGN);

    // 2. 将自己变成独立的会话
    if (fork() > 0)
        exit(0);
    setsid();

    // 3. 更改当前调用进程的工作目录
    if (!cwd.empty())
        chdir(cwd.c_str());

    // 4. 标准输入,标准输出,标准错误重定向至/dev/null
    int fd = open(nullfile.c_str(), O_RDWR);
    if(fd > 0)
    {
        dup2(fd, 0);
        dup2(fd, 1);
        dup2(fd, 2);
        close(fd);
    }
}

daemom 函数 - 简化创建过程

使用 daemom 函数可以方便的创建守护进程,该函数自动完成上述的 4 个过程

cpp 复制代码
#include <unistd.h>

int daemon(int nochdir, int noclose);
  • nochdir:为 0 时,切换工作目录到 /;非 0 时,保持当前工作目录

  • noclose:为 0 时,重定向 stdin/stdout/stderr 到 /dev/null;非 0 时,保持原样

  • 成功:返回 0

  • 失败:返回 -1,设置 errno

终端是什么

终端 是 Linux/Unix 系统中一个非常核心但又容易混淆的概念。简单来说,终端是用户与系统内核进行交互的入口

可以从三个层面来理解它:物理层面、逻辑层面,以及你现在正在使用的"东西"。


1. 历史的起源:物理终端

在计算机早期,大型主机(Mainframe)昂贵且庞大,用户无法直接坐在主机前操作。

  • 物理终端 :由键盘 (输入)和显示器(输出)组成的一套设备,通过串行线缆连接到主机。

  • 每个坐在终端前的人,相当于获得了主机的一个会话

  • 虽然现在这种硬件设备很少见了,但它的概念被继承了下来。当你按下 Ctrl+Alt+F2 切换到 Linux 的纯黑屏界面时,那个界面就叫 TTY(Teletypewriter,电传打字机),它模拟的就是这种物理终端。


2. 现在的形态:终端模拟器

在现代图形界面(如 Windows、macOS、Linux 桌面)下,我们通常打开的"黑框框"并不是真正的物理终端硬件,而是终端模拟器(Terminal Emulator)。

它是一个应用程序,用来模拟古老物理终端的行为。

  • 常见的终端模拟器:GNOME Terminal(Linux 默认)、Konsole、iTerm2(macOS)、Windows Terminal、XShell、SecureCRT。

  • 本质 :它捕获你的键盘输入,显示程序的输出,但它本身并不理解你输入的命令(如 lscd)。它只是一个"传话筒"。


3. 核心机制:终端 vs Shell

这是最容易被混淆的地方。你打开一个"黑框框",里面在运行程序,但终端Shell是两回事:

  • 终端 :负责输入/输出(I/O)。

    • 它提供一个窗口,接收键盘输入,显示文字输出。

    • 它本身不解析命令。

  • Shell :负责解释和执行命令。

    • 它是一个用户态程序(如 bashzshsh)。

    • 它读取终端发来的输入,解析命令(如 ls),调用内核执行,然后将结果返回给终端显示。

类比

如果系统是一个公司:

  • 终端 (Terminal)是公司的前台/接待窗口(负责递纸条、展示结果)。

  • Shell 是坐在前台后面的执行人员(负责看懂纸条上的字,去干活,然后把结果拿回前台)。

验证方法

你可以打开终端,输入 echo $SHELL 查看当前 Shell 是什么。当你输入命令时,是 Shell 在工作;当你调整窗口大小、复制粘贴文字时,是终端模拟器在工作。

4. 常见的"终端"相关名词辨析

在日常工作中,你可能会听到以下说法,它们的含义各不相同:

名词 含义
TTY Teletypewriter 的缩写。在 Linux 中通常指物理终端或虚拟控制台(按 Ctrl+Alt+F1~F6 切换到的黑屏)。
PTS Pseudoterminal Slave(伪终端从设备)。当你在图形界面打开一个终端窗口,或者通过 SSH 远程连接时,分配的就是 PTS(如 /dev/pts/0)。
Terminal 泛指终端,可以是 TTY,也可以是 PTS。
Shell 命令行解释器,运行在终端之上。
Console 控制台。在 Linux 中,通常指物理连接的那一套键盘显示器(即 TTY1),权限级别通常高于普通终端。

总结 :你每次敲命令的那个"黑框框",在技术层面上是一个终端模拟器 ,里面运行着一个 Shell。终端负责让你"看见"和"输入",Shell 负责"干活"。

前台进程与后台进程

在 Linux 系统中,前台进程后台进程 是进程在终端会话中的两种运行模式,核心区别在于是否占用终端的输入输出控制权


1. 前台进程

定义

前台进程是指当前与终端交互的进程。它会独占终端的标准输入 (键盘)、标准输出 (屏幕)和标准错误。在它运行期间,用户无法在该终端执行其他命令,除非它结束或被挂起。

特点

  • 占用终端 Shell,处于"正在运行"状态。

  • 可以接收来自键盘的信号(如 Ctrl+C 终止、Ctrl+Z 挂起)。

  • 通常是用户直接执行的命令(如 vimtopping)。

  • 如果用 ctrl + z 暂停正在运行的前台进程,那么 bash 会被提到前台运行,接收用户输入的指令

示例

bash 复制代码
bash

# 直接运行一个命令,它默认在前台运行
ping baidu.com

此时终端会被 ping 的输出填满,无法输入其他命令。


2. 后台进程

定义

后台进程是指在后台运行的进程,不占用终端输入,但仍然可能向终端输出信息。用户可以在同一终端继续执行其他命令。

特点

  • 终端提示符立即返回,用户可以继续工作。

  • 无法直接接收键盘信号(如 Ctrl+C 无法直接终止后台进程)。

  • 如果尝试从终端读取输入(如 read 命令),进程会被挂起(停止)。

如何启动后台进程
在命令末尾加上 & 符号。

bash 复制代码
bash

# 在后台运行 ping
ping baidu.com > /dev/null &

此时终端会输出类似 [1] 12345 的信息,表示后台进程号和进程 PID。用户可以继续输入其他命令。

作业控制

  • jobs:查看当前终端下的所有的后台进程。
bash 复制代码
[hxh@VM-16-12-centos 2026_3_24]$ jobs
[1]   Running                 ./test >> text1.txt &
[2]-  Running                 ./test >> text2.txt &
[3]+  Running                 ./test >> text3.txt &
  • fg + 后台进程号:将后台进程调回前台。

  • Ctrl+Z:挂起当前前台进程(使其停止,不运行,会显示给它分配的后台进程号)。

  • bg + 后台进程号:将挂起的前台进程转为后台运行。


3. 关键区别总结

特性 前台进程 后台进程
终端占用 独占终端 不占用终端输入
用户交互 可以接收键盘输入 无法接收键盘输入
终端关闭影响 通常进程终止 可能被终止(取决于是否脱离终端)
信号响应 可以响应 Ctrl+CCtrl+Z 需要 kill 命令发送信号
启动方式 直接执行命令 命令后加 &,或使用 bg 转换

4. 后台进程与守护进程的区别

很多初学者会混淆后台进程守护进程

  • 后台进程 :仍然依附于某个终端(会话)。当终端关闭或用户退出登录时,后台进程通常会收到 SIGHUP 信号而终止。

  • 守护进程(Daemon) :完全脱离终端,独立运行在后台,生命周期不受终端控制(如 sshdnginx)。

如果需要让进程彻底脱离终端,可以使用:

  • nohup command &:忽略 SIGHUP 信号,并将输出重定向到 nohup.out

  • 或使用 disown 命令将已有后台作业从当前 Shell 的作业表中移除。

  • 更规范的做法是使用 systemd 或编写守护进程脚本。


5. 实用场景

  • 前台运行:交互式程序(编辑器、调试器、需要用户输入的程序)。

  • 后台运行:长时间执行的任务(如压缩大文件、数据导入),避免阻塞终端。

  • 混合使用 :用 Ctrl+Z 挂起前台任务 → bg 将其转入后台 → fg 再调回。

相关推荐
zhixingheyi_tian2 小时前
Linux/Windows 免密登录
linux·运维·服务器
Uso_Magic2 小时前
SQLSERVER__EXPLAIN 常用分析案例。
服务器·数据库·sql
BPM_宏天低代码2 小时前
【宏天技术】企业CRM系统架构:微服务设计实践
运维
Eine .2 小时前
Docker容器技术
运维·docker·容器
尤老师FPGA2 小时前
petalinux制作linux系统flash+sd卡启动
linux·运维·服务器
code_pgf2 小时前
Orin NX 16GB 的 package 安装命令清单 + Docker/工作区目录结构 + bringup 顺序
运维·docker·容器·ros
蓝天居士3 小时前
Linux实用功能代码集(4) —— 线程间消息队列(2)
linux
Name_NaN_None3 小时前
Linux 使用 Remmina 连接 Windows 远程桌面 ——「小白教程」
linux·网络·电脑·远程工作
shepherd1113 小时前
别再无脑 cat 了!后端排查 GB 级生产日志的实战命令
linux·后端