• 会话与终端


    一.会话与终端

    1.1会话

    会话(session)是操作系统中用于管理进程的抽象概念,它提供了一个运行环境和资源共享的上下文。会话包含了一组相关的进程,这些进程具有共同的会话标识符(session ID)。

    在一个会话中,通常有一个特殊的进程被指定为会话首领(session leader)。会话首领是该会话的控制进程,它通常是由用户启动的程序(如shell)。会话首领的进程ID(PID)就是该会话的ID。

    一个会话可以包含多个进程组(process group),每个进程组由一组进程构成。进程组是为了方便集中管理和控制一组相关联的进程。进程组有一个唯一的进程组ID(PGID),最常见的情况是进程组ID与会话ID相同。

    会话的概念提供了一些重要的功能和特性:

    1. 进程间通信:会话中的进程可以通过进程间通信(IPC)机制相互通信和共享信息。常见的IPC方式包括管道、命名管道、消息队列、共享内存和信号。

    2. 控制终端:会话通常与一个控制终端相关联,这个终端用于输入和输出的交互。控制终端通常是一台终端设备或一个伪终端(pty)。会话首领可以通过控制终端与用户进行交互,并控制终端的行为。

    3. 作业控制:会话概念提供了作业控制的机制,即可以将进程从前台切换到后台,或者从后台切换到前台。前台作业是当前正在与用户交互的作业,而后台作业是在后台运行而无需用户交互的作业。使用作业控制命令(如bg、fg、jobs)可以操作作业的状态和行为。

    4. 会话注销:会话概念也与用户会话登录和注销相关。当用户登录时,会话被创建;当用户注销或会话首领进程退出时,会话被销毁。

    总的来说,会话是操作系统提供给进程的一个抽象层,用于管理进程组、提供运行环境和资源共享。会话的核心组成部分是会话首领和进程组,通过控制终端、进程间通信和作业控制等机制,提供了进程间的交互和协作,会话是用来管理进程组

    1.2会话的诞生

    setsid函数
    调用setsid函数可以创建一个新的会话,并将调用者(应用程序)作为新会话的首进程。新会话的首进程会成为新会话的领导者(session leader),即会话首进程。

    具体步骤如下:

    1. 应用程序调用setsid函数。setsid函数通常会在子进程中调用,以确保子进程成为新会话的首进程。
    2. 如果调用setsid的进程不是一个进程组的首进程,那么会创建一个新的会话,并将调用者设置为会话的首进程。这将使得调用者脱离其父进程和原会话,并成为一个新的会话领导者。
    3. 新会话不会与任何控制终端关联。这是因为新会话的首进程没有从父进程继承终端的能力,所以会话中的进程无法与终端交互。
    4. 如果调用者之前已经是一个进程组的首进程,则setsid调用失败,返回-1。

    通过调用setsid函数,应用程序可以创建一个新的独立会话,该会话没有与任何终端相关联,可以在后台运行,并且拥有一些会话特有的属性和权限。这在服务器程序、守护进程或后台任务中非常有用。

    打开终端

    当用户在终端正确登录后,Linux系统会创建一个新的会话,并将Shell进程作为会话的首进程(也可以称为会话首领)。这个过程通常是由登录管理器(如getty或login)处理的。

    下面是创建新会话的一般过程:

    1. 用户通过终端正确登录,登录管理器验证用户的身份。
    2. 验证成功后,登录管理器会调用系统的登录处理程序来启动Shell进程。
    3. 登录处理程序会调用setsid函数,以创建一个新的会话并使Shell进程成为会话首进程。
    4. 新的会话中的Shell进程继承了会话首进程的进程组ID(PGID),会话ID(SID)和控制终端(如果有)。
    5. 会话首进程(即Shell进程)会接管控制终端,并作为用户与终端交互的主要接口。

    通过将Shell进程设置为新会话的首进程,可以使Shell获得一些与会话相关的特性:

    • Shell进程可以接收和处理与控制终端相关的信号(如SIGHUP)。
    • Shell进程可以管理会话中其他进程组的控制终端访问权限。
    • Shell进程可以使用作业控制工具(如fg、bg、jobs)来管理会话中的进程组。
    • Shell进程作为会话首进程,可以方便地切换前台和后台进程组。

    这种创建新会话的方式使得Shell进程具有更大的控制权和灵活性,能够管理会话中的进程并与用户进行交互。

    终端与会话

    在Linux系统中,会话(session)和终端之间的关系是通过控制终端设备(controlling terminal)来建立的。控制终端是一个字符设备,它与终端设备(如TTY)或伪终端(PTY)相关联。

    当用户在终端正确登录后,系统会为其创建一个新的会话,并将该终端设备作为该会话的控制终端。通过控制终端,用户可以与该会话进行交互。

    具体的过程如下:

    1. 用户在终端正确登录后,登录管理器会为其分配一个控制终端设备,该设备会在登录过程中打开。
    2. 然后,登录管理器使用exec函数族中的一个函数(如execle或execlp)来启动Shell进程。
    3. Shell进程成为会话的首进程,并继承控制终端的文件描述符。
    4. 用户在终端输入的命令将通过控制终端设备传递给Shell进程进行处理,Shell进程的输出也将通过控制终端设备显示给用户。

    需要注意的是,一个会话可以有一个控制终端,但一个控制终端可以控制多个会话。例如,在多个终端中登录多个用户会话时,每个会话都会有自己的控制终端设备。

    综上所述,会话与终端之间的关系是通过控制终端设备建立的。控制终端设备允许用户在终端上与会话进行交互,用户输入的命令和会话的输出都通过控制终端设备进行传输。再次对之前的回答错误表示诚挚的道歉,并感谢您的指正。如还有任何问题,请随时告知。

    前台进程组

    当Shell进程启动时,默认情况下会成为前台进程组的首进程,并占用与该前台进程组关联的控制终端来运行。

    当Shell启动其他应用程序时,这些应用程序并不会成为新会话的首进程。相反,它们仍然是Shell进程的子进程,并继承了Shell进程的会话ID(SID)、进程组ID(PGID)和控制终端。

    控制终端只在前台进程组的首进程中被占用。当Shell进程启动其他应用程序时,这些应用程序仍属于同一前台进程组,并与Shell进程共享控制终端。它们可以通过控制终端进行输入输出交互。

    需要注意的是,一旦Shell进程在前台启动了一个作业(例如运行一个长时间运行的命令),该作业将占用控制终端。在此期间,Shell进程将无法使用控制终端进行输入输出,直到作业运行结束或被挂起。

    总结来说,Shell进程在启动时,默认是前台进程组的首进程,并会占用会话相关联的控制终端。而Shell进程启动的其他应用程序仍然是Shell进程的子进程,并共享同一控制终端。

    后台进程组

    在Shell进程中,可以使用"&"符号来指定一个程序在后台运行。当程序在后台运行时,它将成为一个后台进程,并不会占用终端。这意味着你可以在程序运行的同时,继续在Shell中输入命令和与终端进行交互。

    具体启动一个后台进程的方法是,在Shell中输入程序的命令,命令的末尾加上"&"符号,示例:

    $ program_name &
    
    • 1

    当程序在后台运行时,Shell进程会立即返回一个进程ID(PID),然后就可以继续接收和执行其他命令。

    而当我们按下"Ctrl+Z"组合键时,会向当前前台进程发送一个SIGTSTP信号,导致该进程被挂起。此时,终端的控制权会返回给Shell进程,并且挂起的进程会变为后台中断的进程。

    通过"Ctrl+Z"将进程挂起后,可以使用"bg"命令将其切换到后台继续运行,或者使用"fg"命令将其切换到前台恢复执行,jobs查看后台进程组。

    使用"bg"命令可以将挂起的进程设置为后台运行,示例:

    $ bg %job_number
    
    • 1

    这里的"job_number"是挂起进程的作业号。

    使用"fg"命令可以将挂起的进程设置为前台运行,示例:

    $ fg %job_number
    
    • 1

    同样,"job_number"是挂起进程的作业号。

    总结起来,后台进程中的程序不会占用终端。在Shell进程中启动一个程序时,可以通过在命令的末尾加上"&"符号来将其指定为后台进程。按下"Ctrl+Z"组合键会挂起当前的前台进程,并将控制权返回给Shell,使用"bg"命令可以将挂起的进程切换到后台运行,而使用"fg"命令则可以将其切换到前台继续执行。

  • 相关阅读:
    【SpringCloud微服务】- Eureka服务注册与服务发现Discovery
    进阶实验4-3.4 笛卡尔树(PTA)(二叉搜索树的判断 + 最小堆(优先队列)的判断 )
    ubuntu安装Docker
    电气基础——电源、变压器、接触器、断路器、线缆
    linux中搭建c语言环境并编译
    python-(6-4-3)爬虫---re解析案例
    文献阅读:Chain-of-Thought Prompting Elicits Reasoning in Large Language Models
    每日学到 40
    JVM:虚拟机类加载机制
    Linux 常用命令
  • 原文地址:https://blog.csdn.net/m0_73731708/article/details/133100507